Cosigning aggregate bonded transactions

Cosign aggregate transactions pending to be signed.

Prerequisites

This guide assumes that you have received an aggregate transaction. You can follow the guide creating an escrow contract to announce an aggregate transaction.

Method #01: Using the Desktop Wallet

  1. Log in to a cosignatory account that has an impending aggregate bonded transaction waiting to be signed.

  2. At the home page, click on the “partial” tab. Click on the listed transaction and enter your wallet password to sign the transaction.

../../_images/add-signer-2.gif

Method #02: Using the SDK

1. First, check if your account has incoming aggregate transactions that have not been signed. Use the TransactionHttp repository to search all the incoming aggregate transactions pending to be signed by your account.

// replace with account address
const rawAddress = 'TAXQUT-QQNS6J-EJG7PL-C6FRVJ-2USS44-GLMVUL-PGQ';
const address = Address.createFromRawAddress(rawAddress);
const nodeUrl = 'NODE_URL';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();

const searchCriteria = {
  group: TransactionGroup.Partial,
  address,
  pageNumber: 1,
  pageSize: 100,
};
transactionHttp.search(searchCriteria).subscribe(
  (page) => console.log(page.data),
  (err) => console.error(err),
);
// replace with account address
const rawAddress = 'TAXQUT-QQNS6J-EJG7PL-C6FRVJ-2USS44-GLMVUL-PGQ';
const address = symbol_sdk_1.Address.createFromRawAddress(rawAddress);
const nodeUrl = 'NODE_URL';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
const searchCriteria = {
  group: symbol_sdk_1.TransactionGroup.Partial,
  address,
  pageNumber: 1,
  pageSize: 100,
};
transactionHttp.search(searchCriteria).subscribe(
  (page) => console.log(page.data),
  (err) => console.error(err),
);
            TransactionRepository transactionHttp = repositoryFactory.createTransactionRepository();
            TransactionPaginationStreamer streamer = new TransactionPaginationStreamer(transactionHttp);
            List<Transaction> transactions = streamer.search(new TransactionSearchCriteria(TransactionGroup.PARTIAL))
                .toList().toFuture().get();
            System.out.println(transactions);

Copy and save the transaction hash you want to cosign with your account.

  1. Create a function to cosign any AggregateBondedTransaction.

const cosignAggregateBondedTransaction = (
  transaction: AggregateTransaction,
  account: Account,
): CosignatureSignedTransaction => {
  const cosignatureTransaction = CosignatureTransaction.create(transaction);
  return account.signCosignatureTransaction(cosignatureTransaction);
};
const cosignAggregateBondedTransaction = (transaction, account) => {
  const cosignatureTransaction = symbol_sdk_1.CosignatureTransaction.create(
    transaction,
  );
  return account.signCosignatureTransaction(cosignatureTransaction);
};
            BiFunction<AggregateTransaction, Account, CosignatureSignedTransaction> cosignAggregateBondedTransaction = ((transaction, account) -> CosignatureTransaction
                .create(transaction).signWith(account));

3. Define the transaction hash to cosign and the signer account. If you want to cosign a transaction involving a multisig account, you should be using the cosignatory account instead.

// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with private key
const privateKey =
  '0000000000000000000000000000000000000000000000000000000000000000';
const account = Account.createFromPrivateKey(privateKey, networkType);
// replace with node endpoint
// replace with transaction hash to cosign
const transactionHash =
  '0000000000000000000000000000000000000000000000000000000000000000';
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with private key
const privateKey =
  '0000000000000000000000000000000000000000000000000000000000000000';
const account = symbol_sdk_1.Account.createFromPrivateKey(
  privateKey,
  networkType,
);
// replace with node endpoint
// replace with transaction hash to cosign
const transactionHash =
  '0000000000000000000000000000000000000000000000000000000000000000';
            NetworkType networkType = repositoryFactory.getNetworkType().toFuture().get();
            // replace with cosigner private key
            String privateKey = "";
            Account account = Account.createFromPrivateKey(privateKey, networkType);
            // replace with transaction hash to cosign
            String transactionHash = "";

4. Retrieve the complete transaction object from the node using the TransactionHttp repository. At this point, you might want to do some extra checks, like verifying the contents of the transaction. If everything looks ok, cosign the transaction with the signer account. Finally, announce the cosignature to network with transactionHttp.announceAggregateBondedCosignature.

const nodeUrl = 'NODE_URL';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();

transactionHttp
  .getTransaction(transactionHash, TransactionGroup.Partial)
  .pipe(
    map((transaction) =>
      cosignAggregateBondedTransaction(
        transaction as AggregateTransaction,
        account,
      ),
    ),
    mergeMap((cosignatureSignedTransaction) =>
      transactionHttp.announceAggregateBondedCosignature(
        cosignatureSignedTransaction,
      ),
    ),
  )
  .subscribe(
    (announcedTransaction) => console.log(announcedTransaction),
    (err) => console.error(err),
  );
const nodeUrl = 'NODE_URL';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
  .getTransaction(transactionHash, symbol_sdk_1.TransactionGroup.Partial)
  .pipe(
    operators_1.map((transaction) =>
      cosignAggregateBondedTransaction(transaction, account),
    ),
    operators_1.mergeMap((cosignatureSignedTransaction) =>
      transactionHttp.announceAggregateBondedCosignature(
        cosignatureSignedTransaction,
      ),
    ),
  )
  .subscribe(
    (announcedTransaction) => console.log(announcedTransaction),
    (err) => console.error(err),
  );
            TransactionRepository transactionHttp = repositoryFactory.createTransactionRepository();

            TransactionAnnounceResponse announcedTransaction = transactionHttp
                .getTransaction(TransactionGroup.PARTIAL, transactionHash)
                .map(transaction -> cosignAggregateBondedTransaction.apply((AggregateTransaction) transaction, account))
                .flatMap(transactionHttp::announceAggregateBondedCosignature).toFuture().get();
            System.out.println(announcedTransaction);

Once all the participants cosign the transaction, the transaction will be included in a block.

Method #03: Using the CLI

  1. Get all aggregate transactions pending to be cosigned by your account.

symbol-cli transaction search --address TCHBDE-NCLKEB-ILBPWP-3JPB2X-NY64OE-7PYHHE-32I --group Partial
  1. Cosign the aggregate bonded transaction. Replace the hash for the transaction hash retrieved from (1).

symbol-cli transaction cosign --hash A6A374E66B32A3D5133018EFA9CD6E3169C8EEA339F7CCBE29C47D07086E068C