All approvals are executed by the frontend calling polkadot{.js} extension. The backend only saves data that is convenient for user operations.
wallets
id: Unique identifier
name: The multisig wallet name
address: The address of the wallet
parties: The accounts who can approve multisig
threshold: The total number of approvals
balance: Balance of this wallet
multisigs
id: Unique identifier
wallet_id: wallet id
call_hash: call data's hash used to identify call data
call_data: Call's binary data in hex format
to: Transfer destination address
amount: Transfer amount
approved_by: List of approved accounts
executed: Whether this call has been executed
accounts
id: Unique identifier
name: Describe who the account belongs to
address: The account's address
Get all wallets belongs to address
frontend sign the address using user's private key, backend will verify the signature.
The signature in this chapter are all the same.
GET /wallets?address={address}&signature={signature}
Get multisigs of wallet
GET /wallets/{wallet_id}/multisigs?address={address}&signature={signature}
Get a multisig detail
GET /multisigs/{multisig_id}?address={address}&signature={signature}
Response:
{
"call_hash": "0x...",
"call_data": "0x..."
}
Create wallet
POST /wallets
Request params:
{
"name": "Test1",
"address": "1BcbzEwbw9cY3DCL16cG6BHs4gaMk5eJXqeFxFXbq43B3wv",
"signature": "...",
"parties": [
{
"name": "Party1",
"address": "1BcbzEwbw9cY3DCL16cG6BHs4gaMk5eJXqeFxFXbq43B3wv"
},
{
"name": "Party2",
"address": "1JVrK16XZm9vyZjHoYVPjtZ35LvTQ4oyufMoUFTFpAUhath"
},
{
"name": "Party3",
"address": "12pnUavhDJbuy8XYUbKBniPVLdiPzxLdBP4Y5t24vKHtEUPH"
}
]
}
submit 'approved'
PATCH /multisigs/{multisig_id}/approved
Request params:
{
// approval address
"address": "1JVrK16XZm9vyZjHoYVPjtZ35LvTQ4oyufMoUFTFpAUhath",
"signature": "..."
}
submit 'executed'
PATCH /multisigs/{multisig_id}/executed
Request params:
{
// submit address or last approval address
"address": "1JVrK16XZm9vyZjHoYVPjtZ35LvTQ4oyufMoUFTFpAUhath",
"signature": "..."
}
数据库数据
wallets: id, address, threshold, addresses
calls: id, multisig_address, call_hash, call_data, approvals
链上数据
call_hash: call_data multisig_address, call_hash: Multisig
pub struct Multisig<BlockNumber, Balance, AccountId> {
/// The extrinsic when the multisig operation was opened.
when: Timepoint<BlockNumber>,
/// The amount held in reserve of the `depositor`, to be returned once the operation ends.
deposit: Balance,
/// The account who opened it (i.e. the first to approve it).
depositor: AccountId,
/// The approvals achieved so far, including the depositor. Always sorted.
approvals: Vec<AccountId>,
}
ABC 2
A:
multisig_address = create_a_multisig_address_locally([A, B, C], 2);
call Multisig.asMulti(
2,
[B, C],
None,
call_data,
true, // store call on chain
max_weight
)
B:
multisig_address = create_a_multisig_address_locally([A, B, C], 2);
App will show all multisig calls of this multisig_address with info:
call_hash,
when,
the reserve amount of A,
A,
[A],
call Multisig.approveAsMulti(
2,
[A, C],
call_hash,
max_weight