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