Developer Center

Developer Center

  • Getting Started
  • Built-in Features
  • REST API Endpoints
  • Guides
  • Cheat Sheet

›Multisig Account

Getting Started

  • What is Sirius Chain
  • Setting up your workstation
  • Writing your first application

Built-in Features

  • Account
  • Mosaic (SDA)
  • Namespace
  • Transfer Transaction
  • Aggregate Transaction
  • Multisig Account
  • Metadata
  • Account Restriction
  • Cross-Chain Swaps
  • Exchange Market
  • Decentralized Exchange Market
  • Liquidity Provider
  • Storage

Protocol

  • Node
  • Block
  • Cryptography
  • Transaction
  • Validating
  • Consensus Algorithms
  • Receipt
  • Inflation

REST API

  • Overview
  • Tools
  • Serialization
  • Websockets
  • Status Errors

SDKs

  • Overview
  • Architecture
  • Languages
  • Extending Sirius Chain Capabilities
  • SDK Development
  • SDK Documentation

Wallets & Explorers

  • Wallets & Explorers

Cheat Sheet

  • Sirius Chain Cheat Sheet

Guides

  • Overview
  • External Guides
  • Account

    • Creating and opening an account
    • Getting account information
    • Getting the amount of XPX sent to an account
    • Reading transactions from an account

    Account Restriction

    • Preventing spam attacks with account restrictions

    Aggregate Transaction

    • Sending payouts with aggregate-complete transaction
    • Creating an escrow with aggregate bonded transaction
    • Asking for mosaics with aggregate-bonded transaction
    • Signing announced aggregate-bonded transactions

    Block

    • Listening to New Blocks
    • Getting block by height

    Cross Chain Swaps

    • Atomic cross-chain swap between Sirius public and private chains

    Metadata

    • Account Metadata
    • Mosaic Metadata
    • Namespace Metadata
    • Account Metadata (Deprecated since 0.7.0 Sirius Chain release)
    • Mosaic Metadata (Deprecated since 0.7.0 Sirius Chain release)
    • Namespace Metadata (Deprecated since 0.7.0 Sirius Chain release)

    Monitoring

    • Monitor transaction

    Mosaic

    • Creating a mosaic (SDA)
    • Getting the mosaic information
    • Getting the asset identifier behind a namespace with receipts

    Mosaic Levy

    • Modifying Mosaic Supply

    Multisig Account

    • Converting an account to multisig
    • Modifying a multisig account
    • Creating a multi-level multisig-account
    • Sending a multisig transaction

    Namespace

    • Registering a namespace
    • Registering a subnamespace
    • Getting the Namespace information
    • Linking a namespace to a mosaic
    • Linking namespace to account

    Transfer Transaction

    • Transfer transaction
    • Sending an encrypted message

    Storage

    • Data Modification Cancel
    • Data Modification
    • Download Channel
    • Download Payment
    • Drive Closure
    • Finish Download Channel
    • Prepare Bc Drive
    • Replicator Offboarding
    • Replicator Onboarding
    • Storage Payment
    • Verification Payment

Storage

  • Overview
  • Participate
  • External Economy
  • Roles
  • Verification
  • Challenge
  • Rewards
  • Transaction Schemas
  • Built-In Features

    • Drive
    • Replicator
    • Verifier
    • Supercontracts

    Protocols

    • Cross-Block Protocol
    • Fair Streaming

    Storage User Application

    • Overview
    • Getting Started
    • Managing Drives
    • Managing Drive Files
    • Downloading Data

Converting an account to multisig

Create a 1-of-2 multisig account, by adding two cosignatories.

Background Information

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

This shared account appears in Sirius Chain as 1-of-2 multisig. Multisig accounts permit Alice and Bob sharing funds in a separate account, requiring only the signature from one of them to transact.

Multisig 1 of 2

1-of-2 multisig account example

In this guide, you are going to create a 1-of-2 multisig account. In future guides, you will learn how to increase the minimum number of cosignatures required, as well as invite and remove cosignatories from the multisig account.

Prerequisites

  • Text editor or IDE.
  • XPX-Chain-SDK or XPX-Chain-CLI.
  • Finish creating and opening accounts guide.
  • Have one account with XPX.

Getting into some code

  1. First, define the accounts that will be cosignatories of the multisig account. In our case, these are Alice and Bob's addresses. Then, open the account that will be converted into multisig using its private key.
Golang
TypeScript
JavaScript
Java
conf, err := sdk.NewConfig(context.Background(), []string{"http://bctestnet1.brimstone.xpxsirius.io:3000"})
if err != nil {
panic(err)
}

// Use the default http client
client := sdk.NewClient(nil, conf)

accToMultisig, err := client.NewAccountFromPublicKey(os.Getenv("MULTISIG_ACCOUNT_PRIVATE_KEY"))
if err != nil {
panic(err)
}

cosignatory1, err := client.NewAccountFromPrivateKey(os.Getenv("COSIGNATORY_1_PUBLIC_KEY"))
if err != nil {
panic(err)
}

cosignatory2, err := client.NewAccountFromPrivateKey(os.Getenv("COSIGNATORY_2_PUBLIC_KEY"))
if err != nil {
panic(err)
}
const transactionHttp = new TransactionHttp('http://bctestnet1.brimstone.xpxsirius.io:3000');

const privateKey = process.env.PRIVATE_KEY as string; // Private key of the account to convert into multisig
const accToMultisig = Account.createFromPrivateKey(privateKey, NetworkType.TEST_NET);

const cosignatory1PublicKey = '7D08373CFFE4154E129E04F0827E5F3D6907587E348757B0F87D2F839BF88246';
const cosignatory1 = PublicAccount.createFromPublicKey(cosignatory1PublicKey, NetworkType.TEST_NET);
const cosignatory2PublicKey = 'F82527075248B043994F1CAFD965F3848324C9ABFEC506BC05FBCF5DD7307C9D';
const cosignatory2 = PublicAccount.createFromPublicKey(cosignatory2PublicKey, NetworkType.TEST_NET);
const transactionHttp = new TransactionHttp('http://bctestnet1.brimstone.xpxsirius.io:3000');

const privateKey = process.env.PRIVATE_KEY; // Private key of the account to convert into multisig
const accToMultisig = Account.createFromPrivateKey(privateKey, NetworkType.TEST_NET);

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

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

final Account accToMultisig = Account.createFromPrivateKey(privateKey, NetworkType.TEST_NET);

final PublicAccount cosignatory1PublicAccount = PublicAccount.createFromPublicKey(cosignatory1PublicKey, NetworkType.TEST_NET);
final PublicAccount cosignatory2PublicAccount = PublicAccount.createFromPublicKey(cosignatory2PublicKey, NetworkType.TEST_NET);
  1. Create a modify multisig account transaction to convert the shared account into a multisig account. As you want to create a 1-of-2 multisig account, set the minimum signatures required to 1.
Golang
TypeScript
JavaScript
Java
convertIntoMultisigTransaction, err := client.NewModifyMultisigAccountTransaction(
sdk.NewDeadline(time.Hour),
1,
1,
[]*sdk.MultisigCosignatoryModification{
{sdk.Add, cosignatory1.PublicAccount},
{sdk.Add, cosignatory2.PublicAccount},
},
)
if err != nil {
panic(err)
}
const convertIntoMultisigTransaction = ModifyMultisigAccountTransaction.create(
Deadline.create(),
1,
1,
[
new MultisigCosignatoryModification(
MultisigCosignatoryModificationType.Add,
cosignatory1,
),
new MultisigCosignatoryModification(
MultisigCosignatoryModificationType.Add,
cosignatory2,
)],
NetworkType.TEST_NET);
const convertIntoMultisigTransaction = ModifyMultisigAccountTransaction.create(
Deadline.create(),
1,
1,
[
new MultisigCosignatoryModification(
MultisigCosignatoryModificationType.Add,
cosignatory1,
),
new MultisigCosignatoryModification(
MultisigCosignatoryModificationType.Add,
cosignatory2,
)],
NetworkType.TEST_NET);
    final ModifyMultisigAccountTransaction convertIntoMultisigTransaction = ModifyMultisigAccountTransaction.create(
Deadline.create(2, HOURS),
1,
1,
Arrays.asList(
new MultisigCosignatoryModification(
MultisigCosignatoryModificationType.ADD,
cosignatory1PublicAccount
),
new MultisigCosignatoryModification(
MultisigCosignatoryModificationType.ADD,
cosignatory2PublicAccount
)
),
NetworkType.TEST_NET
);
  1. Create an aggregate bonded transaction, wrapping the modify multisig account transaction. This is necessary since Alice and Bob must opt-in to become cosignatories of the new multisig account.
Golang
TypeScript
convertIntoMultisigTransaction.ToAggregate(multisig)

aggregateTransaction, err := client.NewBondedAggregateTransaction(sdk.NewDeadline(time.Hour), []sdk.Transaction{convertIntoMultisigTransaction})
if err != nil {
panic(err)
}
const aggregateTransaction = AggregateTransaction.createBonded(
Deadline.create(),
[convertIntoMultisigTransaction.toAggregate(accToMultisig.publicAccount)],
NetworkType.TEST_NET
);

  1. Sign the aggregate transaction using the private key of the multisig account.

Note:

To make the transaction only valid for your network, include the first block generation hash. Open http://bctestnet1.brimstone.xpxsirius.io:3000/block/1 in a new tab and copy the meta.generationHash value.

Golang
TypeScript
signedAggregateBoundedTransaction, err := accToMultisig.Sign(aggregateTransaction)
if err != nil {
panic(err)
}
const signedAggregateBoundedTransaction = accToMultisig.sign(aggregateTransaction, generationHash);

  1. Before sending an aggregate bonded transaction, the future multisig account needs to lock at least 10 xpx. This transaction is required to prevent network spamming and ensure that the inner transactions are cosigned. After the hash lock transaction has been confirmed, announce the aggregate transaction.
Golang
TypeScript
lockFundsTransaction, err := client.NewLockFundsTransaction(
sdk.NewDeadline(time.Hour),
sdk.XpxRelative(10),
sdk.Duration(1000),
signedAggregateBoundedTransaction,
)
if err != nil {
panic(err)
}

// cosignatory1 will pay for the lock fund
signedLockFundsTransaction, err := cosignatory1.Sign(lockFundsTransaction)
if err != nil {
panic(err)
}

_, err := client.Transaction.Announce(context.Background(), signedLockFundsTransaction)
if err != nil {
panic(err)
}
const lockFundsTransaction = LockFundsTransaction.create(
Deadline.create(),
NetworkCurrencyMosaic.createRelative(10),
UInt64.fromUint(1000),
signedAggregateBoundedTransaction,
NetworkType.TEST_NET);

// // cosignatory1 will pay for the lock fund
const lockFundsTransactionSigned = cosignatory1.sign(lockFundsTransaction, generationHash);

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

  1. Cosign the aggregate transaction with Alice’s account.
CLI
xpx2-cli transaction cosign --hash A6A374E66B32A3D5133018EFA9CD6E3169C8EEA339F7CCBE29C47D07086E068C --profile alice
  1. Cosign the aggregate transaction with Bob’s account.
CLI
xpx2-cli transaction cosign --hash A6A374E66B32A3D5133018EFA9CD6E3169C8EEA339F7CCBE29C47D07086E068C --profile bob
  1. If everything goes well, the account is now multisig, with Alice and Bob being the cosignatories. You can get the list of the multisig accounts where Alice or Bob are cosignatories using the getMultisigAccountInfo function.
Golang
multisigInfo, err := client.Account.GetMultisigAccountInfo(context.Background(), multisig.Address)
if err != nil {
panic(err)
}

What’s next?

Modify the multisig account you just created, converting it into a 2-of-2 multisig following the next guide.

← PreviousModifying a multisig account →
  • Background Information
  • Prerequisites
  • Getting into some code
  • What’s next?
  • Follow our profile
  • Ask development questions
  • Join our Discord channel
  • Explore our Youtube channel
  • Explore Github
Protocol
BlockConsensus AlgorithmsCryptographyInflationNodeReceiptTransactionValidating
Built-in Features
AccountAggregate TransactionCross-Chain SwapsExchange MarketDecentralized Exchange MarketMetadataMosaicMultisig AccountNamespaceTransfer TransactionStorageLiquidity Provider
References
REST APISDKsCheat Sheet
Includes Documentation Forked from NEM
Copyright © 2025 Sirius Chain