This proposal allows you to coordinate signatures from multisig enabled accounts using SEP-0007 style payment requests, iff the accounts opt-in to use this protocol. This would need support from wallet developers.
- All signers on your multisig account will need to have a Stellar Account associated with their public key. Accounts that want to use this protocol should have a data field
multisig_uses_SEP-*
to indicate that multisig is enabled for this account using this proposal (the*
will be filled in once this is formalized into a SEP). - Signers will have a data field, ex:
multisig_coordinator
that specifies a domain (example:mymultisigservice.com
). The domain (mymultisigservice.com) will have astellar.toml
file that contains a fieldMULTISIG_ENDPOINT
that lists an endpoint like so:https://mymultisigservice.com/multisig
. This follows from SEP-0001 around thestellar.toml
file - When you sign a stellar transaction, your wallet will first check the
multisig_uses_SEP-*
field to check if the account can use this multisig coordination approach. It will then fetch the multisig coordinator service domain from themultisig_coordinator
field on your own signer’s account (can be same as the source account) and will fetch theMULTISIG_ENDPOINT
value from the domain's stellar.toml file. The wallet will then send aPOST
request to thisMULTISIG_ENDPOINT
with a signed version of the transaction XDR in a SEP-0007 format (using atx
operation). - mymultisigservice.com multisig server will receive a request on its endpoint (
https://mymultisigservice.com/multisig
) and will pull the source account from the transaction XDR of the SEP-0007 request along with all the signers associated with that the account. It will then verify the signature to ensure that the request is from a valid signer. We can add the public key to the initial request to keep this verification step inexpensive. - mymultisigservice.com multisig server will then create a callback endpoint (example:
https://mymultisigservice.com/<uuid>
) that is bound to this SEP-0007 request; this endpoint will collate signatures.mymultisigservice.com
's multisig server is now the designated coordinator for this multisig request, i.e. it will submit the transaction to the network once it has collected and collated all signatures. - mymultisigservice.com will fetch the
MULTISIG_ENDPOINT
for each signer on the account using the process described in step 2 and 3 above, and for each signer it will generate a new SEP-0007 request by appending the callback endpoint created in step 5 to the original SEP-0007 request using thecallback
field. It will also append thepubkey
param with a value of the signer’s public key. All of this is provisioned for in thetx operation
of SEP-0007. The list of signers should include any signers for specific operations in a transaction where the source account may differ from the transaction's source account. - mymultisigservice.com will submit the new SEP-0007 request generated in step 6 to the
MULTISIG_ENDPOINT
associated with each signer. If theMULTISIG_ENDPOINT
is the same for two different signers, this will constitute two separate requests, one for each signer. Note: these new requests should use signed SEP-0007 requests for an additional layer of security. - someothermultisigservice.com will receive a SEP-0007 request and will first validate the request (similar to step 4) to ensure the signatures are valid against the source accounts. If the SEP-0007 request URI is a signed SEP-0007 request then it should validate the signature against the
origin_domain
(ofmymultisigservice.com
in this case) before proceeding ahead. It will then recognize that this request has acallback
param. It will get a signature from the user by constructing yet another new SEP-0007 request, this time by updating thecallback
,pubkey
,origin_domain
, andsignature
fields. Once it has a signature from the user it willPOST
the signature back to thecallback
endpoint in the SEP-0007 request that it received (it will need to bind thecallback
it sends to the user's wallet with this original SEP-0007 request). The workflow in this scenario is very similar to receving a new request and it's implementation would ideally reflect that. Note: the user’s wallet will be responsible for checking with it’s ownmultisig_coordinator
service for signature requests and this should be generalized into it’s own SEP. Wallets should present these requests for signatures for a multisig account in the same way that they would for any other SEP-0007 request. - mymultisigservice.com will at some point receive all the signatures from the requests it sent out and should collate all these signatures into a single signed transaction, here's some sample code to help with signature collation. The process to handle redundant signatures or failure to receive all signautures will be defined later.
- mymultisigservice.com can then submit this transaction to the stellar network using the
network_passphrase
field on the original SEP-0007 request.
Here are some of the benefits of this approach:
- No need for a second layer network to coordinate multisig requests or signatures, everything is P2P between multisig servers.
- We make minimal use of the data fields on a Stellar account which keeps costs low (networking costs and network fees).
- supports SEP-0007 so we can make use of libraries that will handle SEP-0007 URIs as well as wallets that will implement UIs supporting SEP-0007.
- Signers can choose their own multisig coordination service and this will not introduce any dependencies between services.
Downsides:
- The downside of this approach is that each signer needs their own stellar account where they can maintain the
multisig_coordinator
field.
^^specifically, UUID in point 5 above should be the hash of the original SEP-0007 request to serve as a unique identifier for the request instance across all signers.
This original SEP-0007 request can be considered to be the parent of all the other SEP-0007 requests created as a result by the multisig service and it should be fair to reference all child requests created by the multisig server with the key of (multisig_domain, signer_public_key, hash_of_original_sep-0007_request). This will provide determinism across all instances of a multisig service when trying to scale across different app servers and also when wallets try and fetch the latest requests for their account using a watermark cursor.