Signing raw messages

Hi.

I managed to sign a raw message on a ETH_TEST3 chain.
Is it possible to sign a raw message on a arbitrary network (including those that are not supported), since function createTransaction without parameter assetId does not work?

I would also like to know how to divide and share one key pair between multiple users (fireblocks accounts) and that those users need to provide approval during signing of the transaction. Is that even possible in sandbox?

Hi @timotejv,

I’m part of the Solutions Engineering team at Fireblocks.

The first part of the answer is written under the assumption that you used operation:"RAW" and not operation:"TYPED_MESSAGE", if that’s incorrect please see the end of this part of the answer.

Concerning the part about signing raw messages on arbitrary networks - raw message signing can be used to sign a payload to any blockchain given you know the derivation path for that given chain.
To do this, see the following example:

let { id } = await fbksSDK.createTransaction({
    operation: "RAW",
    extraParameters: {
        rawMessageData: {
            messages: [
                {
                    content: payload,
                    derivationPath: [44, 1, 2, 0, 0]
                }
            ],
            algorithm: SigningAlgorithm.MPC_EDDSA_ED25519
        }
    }
});

The above code will generate a RAW transaction that will get a signature using EDDSA and specified derivation path (due to the 1 in the second location it’s testnet).
So as long as you know the derivation path and the chain uses a supported curve (eddsa or ecdsa at the moment) you can sign any arbitrary message. If you are using RAW signing you can review this article for more details.

If you are referencing the operation:"TYPED_MESSAGE" as the operation you’re talking about, then at the moment it is not possible to sign non supported and (or) non-EVM chains. See this page for more details about using Typed Message signing. Please note however that using RAW signing you are able to perform the same operation as typed message signing on all chains (but as specified before you are also able to sign any arbitrary piece of data).


Concerning the second part - my understanding is that you mean that you’d like for a transaction to not be signed unless several people approve it.
If my understanding is correct, this is possible using the TAP, you are able to configure rules such that a transaction must be approved by several people before it is actually signed. This is covered in the following help-center article .

Please let me know if you have any further questions.

Thanks,
Alon

Hi @agoltzman,

thank you for your answer. You are correct, I am using operation: "RAW.
In the meantime I somehow managed to sign one transaction on chain that is not assetId I specified in the function.

var rawTx = {
        nonce: 0,
        gasPrice: 500000000000,
        gasLimit: 21000,
        to: 'some_Address',
        value: 1,
        chainId: 16
    }

I then serialized this message and called

const { status, id } = await fireblocks.createTransaction({
        operation: TransactionOperation.RAW,
        assetId: "ETH_TEST3",
        source: {
            type: PeerType.VAULT_ACCOUNT,
            id: "0"
        },
        extraParameters: {
            rawMessageData: {
                messages: [{
                    content: serializedTransaction
                }
                ]
            }
        }
    });

With that I received the signature, which I used for sending the transaction to the desired network (with chainId 16). Do you know why that worked, even though I used assetId: "ETH_TEST3"?

I also noticed that option with derivation path and algorithm does not use (allow) parameter source. How to set the signer of the transaction in that case?

I can’t access the two articles from the help-center you posted. It seems I need to request acces here. Is that correct or should I be able to access them without that?

Thank you for your help.

Hi @agoltzman,

in the meantime I figured out that that option with derivation path and algorithm by default uses address from valut with id 0 to sign a transaction. How to set/change the signer (address) of the transaction in that case?

Also, I would like to know if it is somehow possible to get the private key of the address with which the transaction is signed (so, private key of the source address).

Thank you.

Hi @timotejv ,

We have no visibility on what is being signed when using raw message (most of the time) - this is due to the fact we’re signing a hash. Specifically with EVMs, the chainId parameter is not exposed to us as part of the RAW signing process, thus we simply sign whatever is provided (i.e. any arbitrary piece of data).

Concerning the source parameter - derivation path (for example 44,x,y,0,0) replaces it, the third parameter (denote y above) is the vault account Id to use, thus the usage of source is redundant and shouldn’t be provided. The wallet that will be used is determined by the x value above, where 1 is all testnets and 60 is all EVMs.

Getting the private key from a signature or via our system (in a non-disaster recovery fashion) is not possible. To what purpose would you need the private key of the source address?

Thanks.

Hi @agoltzman,

thank you very much for your answers, it helped us a lot.

Regarding the private key, the account I am currently using is used for testing and knowing the private key would ease it to a large degree. But if getting it is not possible, we will try to do it without it.

I have for now only one more question about TAP. Since I cannot access the article from help-center (I requested access a few days ago, but still did not get an answer), do you know if anywhere else there is something written about it or if you could provided an example of how to configure rules such that a transaction must be approved by several people before it is actually signed?

Thank you.