Skip to content

Examples: Off chain AggregateComplete

Chun Lam edited this page Nov 18, 2021 · 4 revisions

Let say, as example, Alice and Bob wanted to exchange 2 asset between them. Without using on-chain cosign, they can do a off-chain cosign.

import { NetworkType, Mosaic, PlainMessage, Deadline, TransferTransaction, 
    Account, PublicAccount, TransactionHttp, NamespaceId, UInt64, AggregateTransaction, TransactionMapping, 
    CosignatureTransaction, CosignatureSignedTransaction, AggregateTransactionService } from "tsjs-xpx-chain-sdk";

let networkType = NetworkType.TEST_NET;
const generationHash = "<please get it from 1st block>";
let apiUrl = "https://bctestnet1.brimstone.xpxsirius.io";

// Alice as initiator

let alicePrivateKey = "<alicePrivateKey>";
let bobPublicKey = "<bobPublicKey>";

let aliceAccount = Account.createFromPrivateKey(alicePrivateKey, networkType);
let bobPublicAccount = PublicAccount.createFromPublicKey(bobPublicKey, networkType);

let transferToBob = TransferTransaction.create(
    Deadline.create(), // default 2 hours
    bobPublicAccount.address,
    [
        new Mosaic(new NamespaceId("alicecoin"), UInt64.fromUint(10)) // sending 10 alicecoin via namespace
    ],
    PlainMessage.create("I am sending you 10 AliceCoin")
)

let transferToAlice = TransferTransaction.create(
    Deadline.create(), // default 2 hours
    aliceAccount.address,
    [
        new Mosaic(new NamespaceId("bobcoin"), UInt64.fromUint(10)) // sending 10 bobcoin via namespace
    ],
    PlainMessage.create("I am sending you 10 BobCoin")
)

// Aggregate both transaction together as Aggregate Complete
let aggregateTxn = AggregateTransaction.createComplete(
    Deadline.create(),
    [
        transferToAlice.toAggregate(bobPublicAccount), // aggreagete and set bob account to sign this transaction
        transferToBob.toAggregate(aliceAccount.publicAccount), // aggreagete and set Alice account to sign this transaction
    ],
    networkType
)

// Alice sign the aggregateTxn
let aliceSignedAggregateTxn = aliceAccount.sign(aggregateTxn, generationHash);

// Not announcing the transaction directly, as it will fail, it does not have the complete signature
let payloadToCosign = aliceSignedAggregateTxn.payload;

// send the payload to Bob, it is a long hexadecimal string

// -------------------------------------------------------
// Here onward is Bob

// map back the payload to transaction, and review it
let transaction = TransactionMapping.createFromPayload(payloadToCosign); // might need to cast to AggregateTransaction instance

// if everything ok, cosign it
let bobAccount = Account.createFromPrivateKey("<bobPrivateKey>", networkType);
let cosignedSignature = CosignatureTransaction.signTransactionPayload(payloadToCosign);

cosignedSignature.signature // pass it back to Alice
cosignedSignature.signer // pass it back to Alice, optional

//---------------------------------------------------------
// Back to Alice

let cosignedSignedTransaction = new CosignatureSignedTransaction(aliceSignedAggregateTxn.hash, cosignedSignatureFromBob, bobPublicAccount.publicKey);

let fullySignedAggregateTxn = AggregateTransactionService.addCosignatures(aliceSignedAggregateTxn, [cosignedSignedTransaction]);

// or you can recreate the transaction with the previous payload and sign again
let recreatedUnsignedTransaction = TransactionMapping.createFromPayload(payloadToCosign); // might need to cast to AggregateTransaction instance
let fullySignedAggregateTxn = recreatedUnsignedTransaction.signTransactionGivenSignatures(aliceAccount, [cosignedSignedTransaction], generationHash);

// finally announce it 
let transactionHttp = new TransactionHttp(apiUrl);
transactionHttp.announce(fullySignedAggregateTxn);

// the rest is checking the transaction status
Clone this wiki locally