src/multisig.js
/**
 * mergeMultisigTransactions takes a list of multisig transaction blobs, and merges them.
 * @param multisigTxnBlobs a list of blobs representing encoded multisig txns
 * @returns typed array msg-pack encoded multisig txn
 */
mergeMultisigTransactions takes a list of multisig transaction blobs, and merges them.
@param multisigTxnBlobs a list of blobs representing encoded multisig txns
@returns typed array msg-pack encoded multisig txn
mergeMultisigTransactions takes a list of multisig transaction blobs and merges them . @param multisigTxnBlobs a list of blobs representing encoded multisig txns @returns typed array msg - pack encoded multisig txn
function mergeMultisigTransactions(multisigTxnBlobs) {
    if (multisigTxnBlobs.length < 2) {
        throw ERROR_MULTISIG_MERGE_LESSTHANTWO;
    }
    const refSigTx = encoding.decode(multisigTxnBlobs[0]);
    const refSigAlgoTx = MultisigTransaction.from_obj_for_encoding(refSigTx.txn);
    const refTxIDStr = refSigAlgoTx.txID().toString();
    const from = address.encodeAddress(refSigTx.txn.snd);
    let newSubsigs = refSigTx.msig.subsig;
    for (let i = 0; i < multisigTxnBlobs.length; i++) {
        let unisig = encoding.decode(multisigTxnBlobs[i]);
        let unisigAlgoTxn = MultisigTransaction.from_obj_for_encoding(unisig.txn);
        if (unisigAlgoTxn.txID().toString() !== refTxIDStr) {
            throw ERROR_MULTISIG_MERGE_MISMATCH;
        }
        if (unisig.msig.subsig.length !== refSigTx.msig.subsig.length) {
            throw ERROR_MULTISIG_MERGE_WRONG_PREIMAGE;
        }
        let preimg = {
            "version": unisig.msig.v,
            "threshold": unisig.msig.thr,
            "pks": unisig.msig.subsig.map(subsig => {
                return subsig.pk;
            }),
        };
        if (from !== address.encodeAddress(address.fromMultisigPreImg(preimg))) {
            throw ERROR_MULTISIG_MERGE_WRONG_PREIMAGE;
        }
        newSubsigs = unisig.msig.subsig.map((uniSubsig, index) => {
            let current = newSubsigs[index];
            if (current.s) {
                if (uniSubsig.s && Buffer.compare(Buffer.from(uniSubsig.s), Buffer.from(current.s)) !== 0) {
                    throw ERROR_MULTISIG_MERGE_SIG_MISMATCH;
                }
                return {
                    "pk": current.pk,
                    "s": current.s,
                }
            } else if (uniSubsig.s) {
                return {
                    "pk": current.pk,
                    "s": uniSubsig.s,
                }
            }
            return current;
        });
    }
    let msig = {
        "v": refSigTx.msig.v,
        "thr": refSigTx.msig.thr,
        "subsig": newSubsigs,
    };
    let sTxn = {
        "msig": msig,
        "txn": refSigTx.txn,
    };
    return new Uint8Array(encoding.encode(sTxn));
}
function mergeMultisigTransactions ( multisigTxnBlobs ) { if ( multisigTxnBlobs . length < 2 ) { throw ERROR_MULTISIG_MERGE_LESSTHANTWO ; } const refSigTx = encoding . decode ( multisigTxnBlobs [ 0 ] ) ; const refSigAlgoTx = MultisigTransaction . from_obj_for_encoding ( refSigTx . txn ) ; const refTxIDStr = refSigAlgoTx . txID ( ) . toString ( ) ; const from = address . encodeAddress ( refSigTx . txn . snd ) ; let newSubsigs = refSigTx . msig . subsig ; for ( let i = 0 ; i < multisigTxnBlobs . length ; i ++ ) { let unisig = encoding . decode ( multisigTxnBlobs [ i ] ) ; let unisigAlgoTxn = MultisigTransaction . from_obj_for_encoding ( unisig . txn ) ; if ( unisigAlgoTxn . txID ( ) . toString ( ) !== refTxIDStr ) { throw ERROR_MULTISIG_MERGE_MISMATCH ; } if ( unisig . msig . subsig . length !== refSigTx . msig . subsig . length ) { throw ERROR_MULTISIG_MERGE_WRONG_PREIMAGE ; } let preimg = { "version" : unisig . msig . v , "threshold" : unisig . msig . thr , "pks" : unisig . msig . subsig . map ( subsig => { return subsig . pk ; } ) , } ; if ( from !== address . encodeAddress ( address . fromMultisigPreImg ( preimg ) ) ) { throw ERROR_MULTISIG_MERGE_WRONG_PREIMAGE ; } newSubsigs = unisig . msig . subsig . map ( ( uniSubsig , index ) => { let current = newSubsigs [ index ] ; if ( current . s ) { if ( uniSubsig . s && Buffer . compare ( Buffer . from ( uniSubsig . s ) , Buffer . from ( current . s ) ) !== 0 ) { throw ERROR_MULTISIG_MERGE_SIG_MISMATCH ; } return { "pk" : current . pk , "s" : current . s , } } else if ( uniSubsig . s ) { return { "pk" : current . pk , "s" : uniSubsig . s , } } return current ; } ) ; } let msig = { "v" : refSigTx . msig . v , "thr" : refSigTx . msig . thr , "subsig" : newSubsigs , } ; let sTxn = { "msig" : msig , "txn" : refSigTx . txn , } ; return new Uint8Array ( encoding . encode ( sTxn ) ) ; }
mergeMultisigTransactions takes a list of multisig transaction blobs, and merges them.
mergeMultisigTransactions takes a list of multisig transaction blobs and merges them .
// check multisig has same preimage as reference // now, we can merge // we convert the Uint8Arrays uniSubsig.s and current.s to Buffers here because (as // of Dec 2020) React overrides the buffer package with an older version that does // not support Uint8Arrays in the comparison function. See this thread for more // info: https://github.com/algorand/js-algorand-sdk/issues/252 // mismatch