Converting an account to multisig

The purpose of this guide is to create a 1-of-2 multisig account, by adding two cosignatories.

Background

Alice and Bob live together and have separate accounts. They also have a shared account so that if Bob is out shopping, he can buy groceries for both him and Alice.

This shared account is in NEM translated as 1-of-2 multisig, meaning that one cosignatory needs to cosign the transaction to be included in a block.

../../_images/guides-accounts-multisig-1-of-2.png

1-of-2 multisig account example

Remember that a multisig account has cosignatories accounts, and it cannot start transactions itself. Only the cosignatories can initiate transactions.

Prerequisites

Let’s get into some code

The first step is to define who will be the cosignatories of the multisig account. Then, open the account that will be converted into multisig by providing its private key.

// Replace with the private key of the account that you want to convert into multisig
const privateKey = process.env.PRIVATE_KEY as string;

// Replace with cosignatories public keys
const cosignatory1PublicKey = '7D08373CFFE4154E129E04F0827E5F3D6907587E348757B0F87D2F839BF88246';
const cosignatory2PublicKey = 'F82527075248B043994F1CAFD965F3848324C9ABFEC506BC05FBCF5DD7307C9D';

const account = Account.createFromPrivateKey(privateKey, NetworkType.MIJIN_TEST);

const cosignatory1 = PublicAccount.createFromPublicKey(cosignatory1PublicKey, NetworkType.MIJIN_TEST);
const cosignatory2 = PublicAccount.createFromPublicKey(cosignatory2PublicKey, NetworkType.MIJIN_TEST);
        // Replace with the private key of the account that you want to convert into multisig
        final String privateKey = "";

        // Replace with cosignatories public keys
        final String cosignatory1PublicKey = "";
        final String cosignatory2PublicKey = "";

        final Account account = Account.createFromPrivateKey(privateKey, NetworkType.MIJIN_TEST);

        final PublicAccount cosignatory1PublicAccount = PublicAccount.createFromPublicKey(cosignatory1PublicKey, NetworkType.MIJIN_TEST);
        final PublicAccount cosignatory2PublicAccount = PublicAccount.createFromPublicKey(cosignatory2PublicKey, NetworkType.MIJIN_TEST);
// Replace with the private key of the account that you want to convert into multisig
const privateKey = process.env.PRIVATE_KEY;

// Replace with cosignatories public keys
const cosignatory1PublicKey = '7D08373CFFE4154E129E04F0827E5F3D6907587E348757B0F87D2F839BF88246';
const cosignatory2PublicKey = 'F82527075248B043994F1CAFD965F3848324C9ABFEC506BC05FBCF5DD7307C9D';

const account = Account.createFromPrivateKey(privateKey, NetworkType.MIJIN_TEST);

const cosignatory1 = PublicAccount.createFromPublicKey(cosignatory1PublicKey, NetworkType.MIJIN_TEST);
const cosignatory2 = PublicAccount.createFromPublicKey(cosignatory2PublicKey, NetworkType.MIJIN_TEST);

The next step is to convert the account into a multisig account by setting a modify multisig account transaction. As it is a 1-of-2 multisig account, set the minimum signatures to 1.

const convertIntoMultisigTransaction = ModifyMultisigAccountTransaction.create(
    Deadline.create(),
    1,
    1,
    [
        new MultisigCosignatoryModification(
            MultisigCosignatoryModificationType.Add,
            cosignatory1,
        ),
        new MultisigCosignatoryModification(
            MultisigCosignatoryModificationType.Add,
            cosignatory2,
        )],
    NetworkType.MIJIN_TEST
);
        final ModifyMultisigAccountTransaction convertIntoMultisigTransaction = ModifyMultisigAccountTransaction.create(
            Deadline.create(2, HOURS),
            1,
            1,
            Arrays.asList(
                new MultisigCosignatoryModification(
                    MultisigCosignatoryModificationType.ADD,
                    cosignatory1PublicAccount
                ),
                new MultisigCosignatoryModification(
                    MultisigCosignatoryModificationType.ADD,
                    cosignatory2PublicAccount
                )
            ),
            NetworkType.MIJIN_TEST
        );
const convertIntoMultisigTransaction = ModifyMultisigAccountTransaction.create(
    Deadline.create(),
    1,
    1,
    [
        new MultisigCosignatoryModification(
            MultisigCosignatoryModificationType.Add,
            cosignatory1,
        ),
        new MultisigCosignatoryModification(
            MultisigCosignatoryModificationType.Add,
            cosignatory2,
        )],
    NetworkType.MIJIN_TEST
);

Finally, multisig account signs and announces the transaction.

const signedTransaction = account.sign(convertIntoMultisigTransaction);

const transactionHttp = new TransactionHttp('http://localhost:3000');

transactionHttp.announce(signedTransaction).subscribe(
    x => console.log(x),
    err => console.error(err)
);
        final TransactionHttp transactionHttp = new TransactionHttp("http://localhost:3000");
        final SignedTransaction signedTransaction = account.sign(convertIntoMultisigTransaction);
        transactionHttp.announce(signedTransaction).toFuture().get();
const signedTransaction = account.sign(convertIntoMultisigTransaction);

const transactionHttp = new TransactionHttp('http://localhost:3000');

transactionHttp.announce(signedTransaction).subscribe(
    x => console.log(x),
    err => console.error(err)
);

If everything goes well, Alice and Bob should be cosignatories of the multisig account.

const accountHttp = new AccountHttp('http://localhost:3000');

// Replace with address
const address = 'SCSGBN-HYJD6P-KJHACX-3R2BI3-QUMMOY-QSNW5J-ICLK';

accountHttp.getMultisigAccountInfo(Address.createFromRawAddress(address)).subscribe(
    accountInfo => console.log(accountInfo),
    err => console.error(err)
);
        final AccountHttp accountHttp = new AccountHttp("http://localhost:3000");

        // Replace with address
        final String addressRaw = "SB2RPH-EMTFMB-KELX2Y-Q3MZTD-RV7DQG-UZEADV-CYKC";

        final Address address = Address.createFromRawAddress(addressRaw);

        final MultisigAccountInfo multisigAccountInfo = accountHttp.getMultisigAccountInfo(address).toFuture().get();

        System.out.println(multisigAccountInfo);
const accountHttp = new AccountHttp('http://localhost:3000');

// Replace with address
const address = 'SCSGBN-HYJD6P-KJHACX-3R2BI3-QUMMOY-QSNW5J-ICLK';

accountHttp.getMultisigAccountInfo(Address.createFromRawAddress(address)).subscribe(
    accountInfo => console.log(accountInfo),
    err => console.error(err)
);

Note

You could also get the list of the multisig accounts where Alice or Bob are cosignatories using getMultisigAccountInfo method.

What’s next?

Try to modify the account, converting it into a 2-of-2 multisig following modifying a multisig account guide.