Repository: algorand/js-algorand-sdk
Pull request #403 (2021-07-15 16:08:41)

Create github engineering template


Patch:
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..8800316
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,30 @@
+---
+name: "\U0001F41C Bug report"
+about: Report a reproducible bug.
+title: ''
+labels: new-bug
+assignees: ''
+
+---
+
+### Subject of the issue
+
+<!-- Describe your issue here. -->
+
+### Your environment
+
+<!--
+* Software version: `algod -v`
+* Node status if applicable: `goal node status`
+* Operating System details. 
+* In many cases log files and cadaver files are also useful to include. Since these files may be large, an Algorand developer may request them later. These files may include public addresses that you're participating with. If that is a concern please be sure to scrub that data.
+-->
+
+### Steps to reproduce
+
+1.
+2.
+
+### Expected behaviour
+
+### Actual behaviour
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..7a16b83
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,23 @@
+---
+name: "\U0001F514 Feature Request"
+about: Suggestions for how we can improve the algorand platform.
+title: ''
+labels: new-feature-request
+assignees: ''
+---
+
+## Problem
+
+<!-- What is the problem that we’re trying to solve? -->
+
+## Solution
+
+<!-- Do you have a potential/suggested solution? Document more than one if possible. -->
+
+## Dependencies
+
+<!-- Does the solution have any team or design dependencies? -->
+
+## Urgency
+
+<!-- What is the urgency here and why? -->
diff --git a/.prettierignore b/.prettierignore
index ab32208..008c450 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -2,3 +2,4 @@ dist
 tests/cucumber/features
 tests/cucumber/browser/build
 tests/browser/bundle.*
+.github
diff --git a/src/client/v2/algod/models/types.ts b/src/client/v2/algod/models/types.ts
index 4f964da..962a2c7 100644
--- a/src/client/v2/algod/models/types.ts
+++ b/src/client/v2/algod/models/types.ts
@@ -691,25 +691,43 @@ export class AssetParams extends BaseModel {
   public metadataHash?: Uint8Array;
 
   /**
-   * (an) Name of this asset, as supplied by the creator.
+   * (an) Name of this asset, as supplied by the creator. Included only when the
+   * asset name is composed of printable utf-8 characters.
    */
   public name?: string;
 
+  /**
+   * Base64 encoded name of this asset, as supplied by the creator.
+   */
+  public nameB64?: Uint8Array;
+
   /**
    * (r) Address of account holding reserve (non-minted) units of this asset.
    */
   public reserve?: string;
 
   /**
-   * (un) Name of a unit of this asset, as supplied by the creator.
+   * (un) Name of a unit of this asset, as supplied by the creator. Included only
+   * when the name of a unit of this asset is composed of printable utf-8 characters.
    */
   public unitName?: string;
 
   /**
-   * (au) URL where more information about the asset can be retrieved.
+   * Base64 encoded name of a unit of this asset, as supplied by the creator.
+   */
+  public unitNameB64?: Uint8Array;
+
+  /**
+   * (au) URL where more information about the asset can be retrieved. Included only
+   * when the URL is composed of printable utf-8 characters.
    */
   public url?: string;
 
+  /**
+   * Base64 encoded URL where more information about the asset can be retrieved.
+   */
+  public urlB64?: Uint8Array;
+
   /**
    * Creates a new `AssetParams` object.
    * @param creator - The address that created this asset. This is the address where the parameters
@@ -728,10 +746,16 @@ export class AssetParams extends BaseModel {
    * @param manager - (m) Address of account used to manage the keys of this asset and to destroy it.
    * @param metadataHash - (am) A commitment to some unspecified asset metadata. The format of this
    * metadata is up to the application.
-   * @param name - (an) Name of this asset, as supplied by the creator.
+   * @param name - (an) Name of this asset, as supplied by the creator. Included only when the
+   * asset name is composed of printable utf-8 characters.
+   * @param nameB64 - Base64 encoded name of this asset, as supplied by the creator.
    * @param reserve - (r) Address of account holding reserve (non-minted) units of this asset.
-   * @param unitName - (un) Name of a unit of this asset, as supplied by the creator.
-   * @param url - (au) URL where more information about the asset can be retrieved.
+   * @param unitName - (un) Name of a unit of this asset, as supplied by the creator. Included only
+   * when the name of a unit of this asset is composed of printable utf-8 characters.
+   * @param unitNameB64 - Base64 encoded name of a unit of this asset, as supplied by the creator.
+   * @param url - (au) URL where more information about the asset can be retrieved. Included only
+   * when the URL is composed of printable utf-8 characters.
+   * @param urlB64 - Base64 encoded URL where more information about the asset can be retrieved.
    */
   constructor({
     creator,
@@ -743,9 +767,12 @@ export class AssetParams extends BaseModel {
     manager,
     metadataHash,
     name,
+    nameB64,
     reserve,
     unitName,
+    unitNameB64,
     url,
+    urlB64,
   }: {
     creator: string;
     decimals: number | bigint;
@@ -756,9 +783,12 @@ export class AssetParams extends BaseModel {
     manager?: string;
     metadataHash?: string | Uint8Array;
     name?: string;
+    nameB64?: string | Uint8Array;
     reserve?: string;
     unitName?: string;
+    unitNameB64?: string | Uint8Array;
     url?: string;
+    urlB64?: string | Uint8Array;
   }) {
     super();
     this.creator = creator;
@@ -773,9 +803,21 @@ export class AssetParams extends BaseModel {
         ? new Uint8Array(Buffer.from(metadataHash, 'base64'))
         : metadataHash;
     this.name = name;
+    this.nameB64 =
+      typeof nameB64 === 'string'
+        ? new Uint8Array(Buffer.from(nameB64, 'base64'))
+        : nameB64;
     this.reserve = reserve;
     this.unitName = unitName;
+    this.unitNameB64 =
+      typeof unitNameB64 === 'string'
+        ? new Uint8Array(Buffer.from(unitNameB64, 'base64'))
+        : unitNameB64;
     this.url = url;
+    this.urlB64 =
+      typeof urlB64 === 'string'
+        ? new Uint8Array(Buffer.from(urlB64, 'base64'))
+        : urlB64;
 
     this.attribute_map = {
       creator: 'creator',
@@ -787,9 +829,12 @@ export class AssetParams extends BaseModel {
       manager: 'manager',
       metadataHash: 'metadata-hash',
       name: 'name',
+      nameB64: 'name-b64',
       reserve: 'reserve',
       unitName: 'unit-name',
+      unitNameB64: 'unit-name-b64',
       url: 'url',
+      urlB64: 'url-b64',
     };
   }
 }
diff --git a/src/multisig.ts b/src/multisig.ts
index c6d1930..fb0f8b5 100644
--- a/src/multisig.ts
+++ b/src/multisig.ts
@@ -49,7 +49,7 @@ interface MultisigMetadataWithPks extends Omit<MultisigMetadata, 'addrs'> {
  * @param pks - ordered list of public keys in this multisig
  * @returns encoded multisig blob
  */
-export function createMultisigTransaction(
+function createMultisigTransaction(
   txnForEncoding: EncodedTransaction,
   { rawSig, myPk }: MultisigOptions,
   { version, threshold, pks }: MultisigMetadataWithPks
@@ -142,6 +142,13 @@ export class MultisigTransaction extends txnBuilder.Transaction {
       { version, threshold, pks }
     );
   }
+
+  // eslint-disable-next-line camelcase
+  static from_obj_for_encoding(
+    txnForEnc: EncodedTransaction
+  ): MultisigTransaction {
+    return super.from_obj_for_encoding(txnForEnc) as MultisigTransaction;
+  }
 }
 
 /**
diff --git a/src/transaction.ts b/src/transaction.ts
index 4f5c62b..b7711c0 100644
--- a/src/transaction.ts
+++ b/src/transaction.ts
@@ -13,6 +13,8 @@ import AnyTransaction, {
   MustHaveSuggestedParamsInline,
   EncodedTransaction,
   EncodedSignedTransaction,
+  EncodedMultisig,
+  EncodedLogicSig,
 } from './types/transactions';
 import { Address } from './types/address';
 
@@ -756,7 +758,7 @@ export class Transaction implements TransactionStorageStructure {
   }
 
   // eslint-disable-next-line camelcase
-  static from_obj_for_encoding(txnForEnc: EncodedTransaction) {
+  static from_obj_for_encoding(txnForEnc: EncodedTransaction): Transaction {
     const txn = Object.create(this.prototype);
     txn.name = 'Transaction';
     txn.tag = Buffer.from('TX');
@@ -1073,18 +1075,53 @@ export function decodeUnsignedTransaction(
   return Transaction.from_obj_for_encoding(partlyDecodedObject);
 }
 
+/**
+ * Object representing a transaction with a signature
+ */
+export interface SignedTransaction {
+  /**
+   * Transaction signature
+   */
+  sig?: Buffer;
+
+  /**
+   * The transaction that was signed
+   */
+  txn: Transaction;
+
+  /**
+   * Multisig structure
+   */
+  msig?: EncodedMultisig;
+
+  /**
+   * Logic signature
+   */
+  lsig?: EncodedLogicSig;
+
+  /**
+   * The signer, if signing with a different key than the Transaction type `from` property indicates
+   */
+  sgnr?: Buffer;
+}
+
 /**
  * decodeSignedTransaction takes a Buffer (from transaction.signTxn) and converts it to an object
  * containing the Transaction (txn), the signature (sig), and the auth-addr field if applicable (sgnr)
  * @param transactionBuffer - the Uint8Array containing a transaction
  * @returns containing a Transaction, the signature, and possibly an auth-addr field
  */
-export function decodeSignedTransaction(transactionBuffer: Uint8Array) {
+export function decodeSignedTransaction(
+  transactionBuffer: Uint8Array
+): SignedTransaction {
   const stxnDecoded = encoding.decode(
     transactionBuffer
   ) as EncodedSignedTransaction;
-  stxnDecoded.txn = Transaction.from_obj_for_encoding(stxnDecoded.txn);
-  return stxnDecoded;
+  const stxn: SignedTransaction = {
+    ...stxnDecoded,
+    txn: Transaction.from_obj_for_encoding(stxnDecoded.txn),
+  };
+  return stxn;
 }
 
 /**
diff --git a/src/types/transactions/encoded.ts b/src/types/transactions/encoded.ts
index a6b7ecd..e762a64 100644
--- a/src/types/transactions/encoded.ts
+++ b/src/types/transactions/encoded.ts
@@ -90,12 +90,12 @@ export interface EncodedTransaction {
   /**
    * fee
    */
-  fee: number;
+  fee?: number;
 
   /**
    * firstRound
    */
-  fv: number;
+  fv?: number;
 
   /**
    * lastRound
@@ -105,7 +105,7 @@ export interface EncodedTransaction {
   /**
    * note
    */
-  note: Buffer;
+  note?: Buffer;
 
   /**
    * from
@@ -130,7 +130,7 @@ export interface EncodedTransaction {
   /**
    * lease
    */
-  lx: Buffer;
+  lx?: Buffer;
 
   /**
    * group


Test patch:
diff --git a/tests/6.Multisig.js b/tests/6.Multisig.ts
similarity index 50%
rename from tests/6.Multisig.js
rename to tests/6.Multisig.ts
index cdadacc..b5624c7 100644
--- a/tests/6.Multisig.js
+++ b/tests/6.Multisig.ts
@@ -1,220 +1,191 @@
-const assert = require('assert');
-const algosdk = require('../index');
-const multisig = require('../src/multisig');
+import assert from 'assert';
+import algosdk from '../index';
+import {
+  MultisigTransaction,
+  MULTISIG_NO_MUTATE_ERROR_MSG,
+  MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG,
+} from '../src/multisig';
+
+const sampleAccount1 = algosdk.mnemonicToSecretKey(
+  'auction inquiry lava second expand liberty glass involve ginger illness length room item discover ahead table doctor term tackle cement bonus profit right above catch'
+);
+const sampleAccount2 = algosdk.mnemonicToSecretKey(
+  'since during average anxiety protect cherry club long lawsuit loan expand embark forum theory winter park twenty ball kangaroo cram burst board host ability left'
+);
+const sampleAccount3 = algosdk.mnemonicToSecretKey(
+  'advice pudding treat near rule blouse same whisper inner electric quit surface sunny dismiss leader blood seat clown cost exist hospital century reform able sponsor'
+);
+
+// Multisig Golden Params
+const sampleMultisigParams: algosdk.MultisigMetadata = {
+  version: 1,
+  threshold: 2,
+  addrs: [sampleAccount1.addr, sampleAccount2.addr, sampleAccount3.addr],
+};
+
+const sampleMultisigAddr = algosdk.multisigAddress(sampleMultisigParams);
+
+describe('Sample Multisig Info', () => {
+  it('is correct', () => {
+    assert.strictEqual(
+      sampleAccount1.addr,
+      'DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA'
+    );
+    assert.strictEqual(
+      sampleAccount2.addr,
+      'BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM'
+    );
+    assert.strictEqual(
+      sampleAccount3.addr,
+      '47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU'
+    );
+    assert.strictEqual(
+      sampleMultisigAddr,
+      'RWJLJCMQAFZ2ATP2INM2GZTKNL6OULCCUBO5TQPXH3V2KR4AG7U5UA5JNM'
+    );
+  });
+});
 
 describe('Multisig Functionality', () => {
   describe('should generate correct partial signature', () => {
     it('first partial sig should match golden main repo result', () => {
-      // Multisig Golden Params
-      const params = {
-        version: 1,
-        threshold: 2,
-        pks: [
-          algosdk.decodeAddress(
-            'DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA'
-          ).publicKey,
-          algosdk.decodeAddress(
-            'BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM'
-          ).publicKey,
-          algosdk.decodeAddress(
-            '47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU'
-          ).publicKey,
-        ],
-      };
-      /* eslint-disable @typescript-eslint/no-unused-vars */
-      const multisigAddr =
-        'RWJLJCMQAFZ2ATP2INM2GZTKNL6OULCCUBO5TQPXH3V2KR4AG7U5UA5JNM';
-      const mnem1 =
-        'auction inquiry lava second expand liberty glass involve ginger illness length room item discover ahead table doctor term tackle cement bonus profit right above catch';
-      const mnem2 =
-        'since during average anxiety protect cherry club long lawsuit loan expand embark forum theory winter park twenty ball kangaroo cram burst board host ability left';
-      const mnem3 =
-        'advice pudding treat near rule blouse same whisper inner electric quit surface sunny dismiss leader blood seat clown cost exist hospital century reform able sponsor';
-      /* eslint-enable @typescript-eslint/no-unused-vars */
-
-      const o = {
-        snd: Buffer.from(
-          algosdk.decodeAddress(
-            'RWJLJCMQAFZ2ATP2INM2GZTKNL6OULCCUBO5TQPXH3V2KR4AG7U5UA5JNM'
-          ).publicKey
-        ),
-        rcv: Buffer.from(
-          algosdk.decodeAddress(
-            'PNWOET7LLOWMBMLE4KOCELCX6X3D3Q4H2Q4QJASYIEOF7YIPPQBG3YQ5YI'
-          ).publicKey
-        ),
-        fee: 1000,
-        amt: 1000,
-        close: Buffer.from(
-          algosdk.decodeAddress(
-            'IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA'
-          ).publicKey
-        ),
-        gh: Buffer.from(
-          '/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp0=',
-          'base64'
-        ),
-        fv: 62229,
-        lv: 63229,
-        gen: 'devnet-v38.0',
-        type: 'pay',
-        note: Buffer.from('RSYiABhShvs=', 'base64'),
-      };
+      const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
+        from: sampleMultisigAddr,
+        to: 'PNWOET7LLOWMBMLE4KOCELCX6X3D3Q4H2Q4QJASYIEOF7YIPPQBG3YQ5YI',
+        amount: 1000,
+        note: new Uint8Array(Buffer.from('RSYiABhShvs=', 'base64')),
+        closeRemainderTo:
+          'IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA',
+        suggestedParams: {
+          fee: 1000,
+          flatFee: true,
+          firstRound: 62229,
+          lastRound: 63229,
+          genesisID: 'devnet-v38.0',
+          genesisHash: '/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp0=',
+        },
+      });
+
+      const { txID, blob } = algosdk.signMultisigTransaction(
+        txn,
+        sampleMultisigParams,
+        sampleAccount1.sk
+      );
 
-      const msigTxn = multisig.MultisigTransaction.from_obj_for_encoding(o);
-      const { sk } = algosdk.mnemonicToSecretKey(mnem1);
-      const msigBlob = msigTxn.partialSignTxn(params, sk);
+      const expectedTxID =
+        'MANN3ESOHQVHFZBAGD6UK6XFVWEFZQJPWO5SQ2J5LZRCF5E2VVQQ';
+      assert.strictEqual(txID, expectedTxID);
 
-      const goldenExpected = Buffer.from(
+      const expectedSignedTxn = Buffer.from(
         'gqRtc2lng6ZzdWJzaWeTgqJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXihc8RAuLAFE0oma0skOoAmOzEwfPuLYpEWl4LINtsiLrUqWQkDxh4WHb29//YCpj4MFbiSgD2jKYt0XKRD86zKCF4RDYGicGvEIAljMglTc4nwdWcRdzmRx9A+G3PIxPUr9q/wGqJc+cJxgaJwa8Qg5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGjdGhyAqF2AaN0eG6Lo2FtdM0D6KVjbG9zZcQgQOk0koglZMvOnFmmm2dUJonpocOiqepbZabopEIf/FejZmVlzQPoomZ2zfMVo2dlbqxkZXZuZXQtdjM4LjCiZ2jEIP6zbDkQFDkAw9pVQsoYNrAP0vgZWRJXzSP2BC+YyDadomx2zfb9pG5vdGXECEUmIgAYUob7o3JjdsQge2ziT+tbrMCxZOKcIixX9fY9w4fUOQSCWEEcX+EPfAKjc25kxCCNkrSJkAFzoE36Q1mjZmpq/OosQqBd2cH3PuulR4A36aR0eXBlo3BheQ==',
         'base64'
       );
-      assert.deepStrictEqual(Buffer.from(msigBlob), goldenExpected);
+      assert.deepStrictEqual(Buffer.from(blob), expectedSignedTxn);
     });
 
     it('second partial sig should match golden main repo result', () => {
-      // Multisig Golden Params
       const oneSigTxn = Buffer.from(
         'gqRtc2lng6ZzdWJzaWeTgqJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXihc8RAuLAFE0oma0skOoAmOzEwfPuLYpEWl4LINtsiLrUqWQkDxh4WHb29//YCpj4MFbiSgD2jKYt0XKRD86zKCF4RDYGicGvEIAljMglTc4nwdWcRdzmRx9A+G3PIxPUr9q/wGqJc+cJxgaJwa8Qg5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGjdGhyAqF2AaN0eG6Lo2FtdM0D6KVjbG9zZcQgQOk0koglZMvOnFmmm2dUJonpocOiqepbZabopEIf/FejZmVlzQPoomZ2zfMVo2dlbqxkZXZuZXQtdjM4LjCiZ2jEIP6zbDkQFDkAw9pVQsoYNrAP0vgZWRJXzSP2BC+YyDadomx2zfb9pG5vdGXECEUmIgAYUob7o3JjdsQge2ziT+tbrMCxZOKcIixX9fY9w4fUOQSCWEEcX+EPfAKjc25kxCCNkrSJkAFzoE36Q1mjZmpq/OosQqBd2cH3PuulR4A36aR0eXBlo3BheQ==',
         'base64'
       );
-      const params = {
-        version: 1,
-        threshold: 2,
-        pks: [
-          algosdk.decodeAddress(
-            'DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA'
-          ).publicKey,
-          algosdk.decodeAddress(
-            'BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM'
-          ).publicKey,
-          algosdk.decodeAddress(
-            '47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU'
-          ).publicKey,
-        ],
-      };
-      /* eslint-disable @typescript-eslint/no-unused-vars */
-      const multisigAddr =
-        'RWJLJCMQAFZ2ATP2INM2GZTKNL6OULCCUBO5TQPXH3V2KR4AG7U5UA5JNM';
-      const mnem1 =
-        'auction inquiry lava second expand liberty glass involve ginger illness length room item discover ahead table doctor term tackle cement bonus profit right above catch';
-      const mnem2 =
-        'since during average anxiety protect cherry club long lawsuit loan expand embark forum theory winter park twenty ball kangaroo cram burst board host ability left';
-      const mnem3 =
-        'advice pudding treat near rule blouse same whisper inner electric quit surface sunny dismiss leader blood seat clown cost exist hospital century reform able sponsor';
-      /* eslint-enable @typescript-eslint/no-unused-vars */
-
-      const o = {
-        snd: Buffer.from(
-          algosdk.decodeAddress(
-            'RWJLJCMQAFZ2ATP2INM2GZTKNL6OULCCUBO5TQPXH3V2KR4AG7U5UA5JNM'
-          ).publicKey
-        ),
-        rcv: Buffer.from(
-          algosdk.decodeAddress(
-            'PNWOET7LLOWMBMLE4KOCELCX6X3D3Q4H2Q4QJASYIEOF7YIPPQBG3YQ5YI'
-          ).publicKey
-        ),
-        fee: 1000,
-        amt: 1000,
-        close: Buffer.from(
-          algosdk.decodeAddress(
-            'IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA'
-          ).publicKey
-        ),
-        gh: Buffer.from(
-          '/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp0=',
-          'base64'
-        ),
-        fv: 62229,
-        lv: 63229,
-        gen: 'devnet-v38.0',
-        type: 'pay',
-        note: Buffer.from('RSYiABhShvs=', 'base64'),
-      };
 
-      const msigTxn = multisig.MultisigTransaction.from_obj_for_encoding(o);
-      const { sk } = algosdk.mnemonicToSecretKey(mnem2);
-      const msigBlob = msigTxn.partialSignTxn(params, sk);
+      const txn = algosdk.makePaymentTxnWithSuggestedParamsFromObject({
+        from: sampleMultisigAddr,
+        to: 'PNWOET7LLOWMBMLE4KOCELCX6X3D3Q4H2Q4QJASYIEOF7YIPPQBG3YQ5YI',
+        amount: 1000,
+        note: new Uint8Array(Buffer.from('RSYiABhShvs=', 'base64')),
+        closeRemainderTo:
+          'IDUTJEUIEVSMXTU4LGTJWZ2UE2E6TIODUKU6UW3FU3UKIQQ77RLUBBBFLA',
+        suggestedParams: {
+          fee: 1000,
+          flatFee: true,
+          firstRound: 62229,
+          lastRound: 63229,
+          genesisID: 'devnet-v38.0',
+          genesisHash: '/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp0=',
+        },
+      });
+
+      const { txID, blob } = algosdk.signMultisigTransaction(
+        txn,
+        sampleMultisigParams,
+        sampleAccount2.sk
+      );
+
+      const expectedTxID =
+        'MANN3ESOHQVHFZBAGD6UK6XFVWEFZQJPWO5SQ2J5LZRCF5E2VVQQ';
+      assert.strictEqual(txID, expectedTxID);
 
-      const finMsigBlob = multisig.mergeMultisigTransactions([
-        msigBlob,
-        oneSigTxn,
-      ]);
-      const goldenExpected = Buffer.from(
+      const expectedBlob = Buffer.from(
+        'gqRtc2lng6ZzdWJzaWeTgaJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXiConBrxCAJYzIJU3OJ8HVnEXc5kcfQPhtzyMT1K/av8BqiXPnCcaFzxEAQIbskY7Dq5x6d7P8SPojCoi+0D7IfIiWdtmDiST9GhVMHnTK/musH3QV5NTnn8qwDdcKifa6ujvg61ldXx9AEgaJwa8Qg5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGjdGhyAqF2AaN0eG6Lo2FtdM0D6KVjbG9zZcQgQOk0koglZMvOnFmmm2dUJonpocOiqepbZabopEIf/FejZmVlzQPoomZ2zfMVo2dlbqxkZXZuZXQtdjM4LjCiZ2jEIP6zbDkQFDkAw9pVQsoYNrAP0vgZWRJXzSP2BC+YyDadomx2zfb9pG5vdGXECEUmIgAYUob7o3JjdsQge2ziT+tbrMCxZOKcIixX9fY9w4fUOQSCWEEcX+EPfAKjc25kxCCNkrSJkAFzoE36Q1mjZmpq/OosQqBd2cH3PuulR4A36aR0eXBlo3BheQ==',
+        'base64'
+      );
+      assert.deepStrictEqual(Buffer.from(blob), expectedBlob);
+
+      const mergedBlob = algosdk.mergeMultisigTransactions([blob, oneSigTxn]);
+
+      const expectedMergedBlob = Buffer.from(
         'gqRtc2lng6ZzdWJzaWeTgqJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXihc8RAuLAFE0oma0skOoAmOzEwfPuLYpEWl4LINtsiLrUqWQkDxh4WHb29//YCpj4MFbiSgD2jKYt0XKRD86zKCF4RDYKicGvEIAljMglTc4nwdWcRdzmRx9A+G3PIxPUr9q/wGqJc+cJxoXPEQBAhuyRjsOrnHp3s/xI+iMKiL7QPsh8iJZ22YOJJP0aFUwedMr+a6wfdBXk1OefyrAN1wqJ9rq6O+DrWV1fH0ASBonBrxCDn8PhNBoEd+fMcjYeLEVX0Zx1RoYXCAJCGZ/RJWHBooaN0aHICoXYBo3R4boujYW10zQPopWNsb3NlxCBA6TSSiCVky86cWaabZ1Qmiemhw6Kp6ltlpuikQh/8V6NmZWXNA+iiZnbN8xWjZ2VurGRldm5ldC12MzguMKJnaMQg/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp2ibHbN9v2kbm90ZcQIRSYiABhShvujcmN2xCB7bOJP61uswLFk4pwiLFf19j3Dh9Q5BIJYQRxf4Q98AqNzbmTEII2StImQAXOgTfpDWaNmamr86ixCoF3Zwfc+66VHgDfppHR5cGWjcGF5',
         'base64'
       );
-      assert.deepStrictEqual(Buffer.from(finMsigBlob), goldenExpected);
+      assert.deepStrictEqual(Buffer.from(mergedBlob), expectedMergedBlob);
     });
   });
 
   describe('should sign keyreg transaction types', () => {
     it('first partial sig should match golden main repo result', () => {
-      // prettier-ignore
-      const rawTxBlob = Buffer.from([129, 163, 116, 120, 110, 140, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 163, 103, 101, 110, 172, 100, 101, 118, 110, 101, 116, 45, 118, 51, 56, 46, 48, 162, 103, 104, 196, 32, 254, 179, 108, 57, 16, 20, 57, 0, 195, 218, 85, 66, 202, 24, 54, 176, 15, 210, 248, 25, 89, 18, 87, 205, 35, 246, 4, 47, 152, 200, 54, 157, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 167, 118, 111, 116, 101, 102, 115, 116, 206, 0, 13, 187, 160, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64]);
-      // prettier-ignore
-      const oneSigTxBlob = Buffer.from([130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 113, 61, 44, 215, 188, 9, 110, 249, 243, 107, 227, 105, 200, 124, 12, 209, 21, 155, 67, 225, 240, 42, 107, 19, 212, 242, 236, 251, 14, 157, 232, 202, 93, 76, 125, 237, 173, 175, 178, 41, 145, 52, 43, 74, 132, 202, 20, 132, 237, 142, 122, 248, 31, 104, 105, 253, 168, 172, 70, 227, 115, 249, 227, 13, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 140, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 163, 103, 101, 110, 172, 100, 101, 118, 110, 101, 116, 45, 118, 51, 56, 46, 48, 162, 103, 104, 196, 32, 254, 179, 108, 57, 16, 20, 57, 0, 195, 218, 85, 66, 202, 24, 54, 176, 15, 210, 248, 25, 89, 18, 87, 205, 35, 246, 4, 47, 152, 200, 54, 157, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 167, 118, 111, 116, 101, 102, 115, 116, 206, 0, 13, 187, 160, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64]);
-      const params = {
-        version: 1,
-        threshold: 2,
-        pks: [
-          algosdk.decodeAddress(
-            'DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA'
-          ).publicKey,
-          algosdk.decodeAddress(
-            'BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM'
-          ).publicKey,
-          algosdk.decodeAddress(
-            '47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU'
-          ).publicKey,
-        ],
-      };
-      const decRawTx = algosdk.decodeObj(rawTxBlob).txn;
-      const msigTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        decRawTx
+      const rawTxBlob = Buffer.from(
+        'jKNmZWXOAAPIwKJmds4ADvnao2dlbqxkZXZuZXQtdjM4LjCiZ2jEIP6zbDkQFDkAw9pVQsoYNrAP0vgZWRJXzSP2BC+YyDadomx2zgAO/cKmc2Vsa2V5xCAyEisr1j3cUzGWF6WqU8Sxwm/j3MryjTYitWl3oUBchqNzbmTEII2StImQAXOgTfpDWaNmamr86ixCoF3Zwfc+66VHgDfppHR5cGWma2V5cmVnp3ZvdGVmc3TOAA27oKZ2b3Rla2TNJxCndm90ZWtlecQgcBvX+5ErB7MIEf8oHZ/ulWPlgC4gJokjGSWPd/qTHoindm90ZWxzdM4AD0JA',
+        'base64'
+      );
+      const decRawTx = algosdk.decodeUnsignedTransaction(rawTxBlob);
+
+      const { txID, blob } = algosdk.signMultisigTransaction(
+        decRawTx,
+        sampleMultisigParams,
+        sampleAccount1.sk
+      );
+
+      const expectedTxID =
+        'E7DA7WTJCWWFQMKSVU5HOIJ5F5HGVGMOZGBIHRJRYGIX7FIJ5VWA';
+      assert.strictEqual(txID, expectedTxID);
+
+      const oneSigTxBlob = Buffer.from(
+        'gqRtc2lng6ZzdWJzaWeTgqJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXihc8RAcT0s17wJbvnza+NpyHwM0RWbQ+HwKmsT1PLs+w6d6MpdTH3tra+yKZE0K0qEyhSE7Y56+B9oaf2orEbjc/njDYGicGvEIAljMglTc4nwdWcRdzmRx9A+G3PIxPUr9q/wGqJc+cJxgaJwa8Qg5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGjdGhyAqF2AaN0eG6Mo2ZlZc4AA8jAomZ2zgAO+dqjZ2VurGRldm5ldC12MzguMKJnaMQg/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp2ibHbOAA79wqZzZWxrZXnEIDISKyvWPdxTMZYXpapTxLHCb+PcyvKNNiK1aXehQFyGo3NuZMQgjZK0iZABc6BN+kNZo2ZqavzqLEKgXdnB9z7rpUeAN+mkdHlwZaZrZXlyZWendm90ZWZzdM4ADbugpnZvdGVrZM0nEKd2b3Rla2V5xCBwG9f7kSsHswgR/ygdn+6VY+WALiAmiSMZJY93+pMeiKd2b3RlbHN0zgAPQkA=',
+        'base64'
       );
-      const mnem1 =
-        'auction inquiry lava second expand liberty glass involve ginger illness length room item discover ahead table doctor term tackle cement bonus profit right above catch';
-      const { sk } = algosdk.mnemonicToSecretKey(mnem1);
-      const msigBlob = msigTxn.partialSignTxn(params, sk);
 
-      assert.deepStrictEqual(Buffer.from(msigBlob), oneSigTxBlob);
+      assert.deepStrictEqual(Buffer.from(blob), oneSigTxBlob);
     });
 
     it('second partial sig with 3rd pk should match golden main repo result', () => {
-      // prettier-ignore
-      const rawOneSigTxBlob = Buffer.from([130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 113, 61, 44, 215, 188, 9, 110, 249, 243, 107, 227, 105, 200, 124, 12, 209, 21, 155, 67, 225, 240, 42, 107, 19, 212, 242, 236, 251, 14, 157, 232, 202, 93, 76, 125, 237, 173, 175, 178, 41, 145, 52, 43, 74, 132, 202, 20, 132, 237, 142, 122, 248, 31, 104, 105, 253, 168, 172, 70, 227, 115, 249, 227, 13, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 129, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 140, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 163, 103, 101, 110, 172, 100, 101, 118, 110, 101, 116, 45, 118, 51, 56, 46, 48, 162, 103, 104, 196, 32, 254, 179, 108, 57, 16, 20, 57, 0, 195, 218, 85, 66, 202, 24, 54, 176, 15, 210, 248, 25, 89, 18, 87, 205, 35, 246, 4, 47, 152, 200, 54, 157, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 167, 118, 111, 116, 101, 102, 115, 116, 206, 0, 13, 187, 160, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64]);
-      // prettier-ignore
-      const twoSigTxBlob = Buffer.from([130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 113, 61, 44, 215, 188, 9, 110, 249, 243, 107, 227, 105, 200, 124, 12, 209, 21, 155, 67, 225, 240, 42, 107, 19, 212, 242, 236, 251, 14, 157, 232, 202, 93, 76, 125, 237, 173, 175, 178, 41, 145, 52, 43, 74, 132, 202, 20, 132, 237, 142, 122, 248, 31, 104, 105, 253, 168, 172, 70, 227, 115, 249, 227, 13, 129, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 130, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 161, 115, 196, 64, 125, 39, 23, 127, 48, 75, 104, 78, 54, 53, 177, 125, 33, 29, 42, 49, 173, 205, 5, 9, 225, 99, 169, 16, 177, 95, 186, 134, 218, 129, 179, 15, 219, 90, 103, 54, 188, 25, 90, 235, 144, 137, 45, 35, 66, 53, 45, 183, 232, 27, 20, 50, 91, 219, 194, 187, 55, 146, 113, 126, 233, 186, 161, 15, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 140, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 163, 103, 101, 110, 172, 100, 101, 118, 110, 101, 116, 45, 118, 51, 56, 46, 48, 162, 103, 104, 196, 32, 254, 179, 108, 57, 16, 20, 57, 0, 195, 218, 85, 66, 202, 24, 54, 176, 15, 210, 248, 25, 89, 18, 87, 205, 35, 246, 4, 47, 152, 200, 54, 157, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 167, 118, 111, 116, 101, 102, 115, 116, 206, 0, 13, 187, 160, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64]);
-      const params = {
-        version: 1,
-        threshold: 2,
-        pks: [
-          algosdk.decodeAddress(
-            'DN7MBMCL5JQ3PFUQS7TMX5AH4EEKOBJVDUF4TCV6WERATKFLQF4MQUPZTA'
-          ).publicKey,
-          algosdk.decodeAddress(
-            'BFRTECKTOOE7A5LHCF3TTEOH2A7BW46IYT2SX5VP6ANKEXHZYJY77SJTVM'
-          ).publicKey,
-          algosdk.decodeAddress(
-            '47YPQTIGQEO7T4Y4RWDYWEKV6RTR2UNBQXBABEEGM72ESWDQNCQ52OPASU'
-          ).publicKey,
-        ],
-      };
-      const decRawTx = algosdk.decodeObj(rawOneSigTxBlob).txn;
-      const msigTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        decRawTx
+      const rawOneSigTxBlob = Buffer.from(
+        'gqRtc2lng6ZzdWJzaWeTgqJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXihc8RAcT0s17wJbvnza+NpyHwM0RWbQ+HwKmsT1PLs+w6d6MpdTH3tra+yKZE0K0qEyhSE7Y56+B9oaf2orEbjc/njDYGicGvEIAljMglTc4nwdWcRdzmRx9A+G3PIxPUr9q/wGqJc+cJxgaJwa8Qg5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGjdGhyAqF2AaN0eG6Mo2ZlZc4AA8jAomZ2zgAO+dqjZ2VurGRldm5ldC12MzguMKJnaMQg/rNsORAUOQDD2lVCyhg2sA/S+BlZElfNI/YEL5jINp2ibHbOAA79wqZzZWxrZXnEIDISKyvWPdxTMZYXpapTxLHCb+PcyvKNNiK1aXehQFyGo3NuZMQgjZK0iZABc6BN+kNZo2ZqavzqLEKgXdnB9z7rpUeAN+mkdHlwZaZrZXlyZWendm90ZWZzdM4ADbugpnZvdGVrZM0nEKd2b3Rla2V5xCBwG9f7kSsHswgR/ygdn+6VY+WALiAmiSMZJY93+pMeiKd2b3RlbHN0zgAPQkA=',
+        'base64'
       );
-      const mnem3 =
-        'advice pudding treat near rule blouse same whisper inner electric quit surface sunny dismiss leader blood seat clown cost exist hospital century reform able sponsor';
-      const { sk } = algosdk.mnemonicToSecretKey(mnem3);
-      const msigBlob = msigTxn.partialSignTxn(params, sk);
 
-      const finMsigBlob = multisig.mergeMultisigTransactions([
-        msigBlob,
+      const decRawTx = algosdk.decodeSignedTransaction(rawOneSigTxBlob).txn;
+
+      const { txID, blob } = algosdk.signMultisigTransaction(
+        decRawTx,
+        sampleMultisigParams,
+        sampleAccount3.sk
+      );
+
+      const expectedTxID =
+        'E7DA7WTJCWWFQMKSVU5HOIJ5F5HGVGMOZGBIHRJRYGIX7FIJ5VWA';
+      assert.strictEqual(txID, expectedTxID);
+
+      const finMsigBlob = algosdk.mergeMultisigTransactions([
+        blob,
         new Uint8Array(rawOneSigTxBlob),
       ]);
+
+      const twoSigTxBlob = Buffer.from(
+        'gqRtc2lng6ZzdWJzaWeTgqJwa8QgG37AsEvqYbeWkJfmy/QH4QinBTUdC8mKvrEiCairgXihc8RAcT0s17wJbvnza+NpyHwM0RWbQ+HwKmsT1PLs+w6d6MpdTH3tra+yKZE0K0qEyhSE7Y56+B9oaf2orEbjc/njDYGicGvEIAljMglTc4nwdWcRdzmRx9A+G3PIxPUr9q/wGqJc+cJxgqJwa8Qg5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKGhc8RAfScXfzBLaE42NbF9IR0qMa3NBQnhY6kQsV+6htqBsw/bWmc2vBla65CJLSNCNS236BsUMlvbwrs3knF+6bqhD6N0aHICoXYBo3R4boyjZmVlzgADyMCiZnbOAA752qNnZW6sZGV2bmV0LXYzOC4womdoxCD+s2w5EBQ5AMPaVULKGDawD9L4GVkSV80j9gQvmMg2naJsds4ADv3CpnNlbGtlecQgMhIrK9Y93FMxlhelqlPEscJv49zK8o02IrVpd6FAXIajc25kxCCNkrSJkAFzoE36Q1mjZmpq/OosQqBd2cH3PuulR4A36aR0eXBlpmtleXJlZ6d2b3RlZnN0zgANu6Cmdm90ZWtkzScQp3ZvdGVrZXnEIHAb1/uRKwezCBH/KB2f7pVj5YAuICaJIxklj3f6kx6Ip3ZvdGVsc3TOAA9CQA==',
+        'base64'
+      );
+
       assert.deepStrictEqual(Buffer.from(finMsigBlob), twoSigTxBlob);
     });
 
@@ -226,11 +197,11 @@ describe('Multisig Functionality', () => {
       // prettier-ignore
       const allThreeBlob = Buffer.from([130, 164, 109, 115, 105, 103, 131, 166, 115, 117, 98, 115, 105, 103, 147, 130, 162, 112, 107, 196, 32, 27, 126, 192, 176, 75, 234, 97, 183, 150, 144, 151, 230, 203, 244, 7, 225, 8, 167, 5, 53, 29, 11, 201, 138, 190, 177, 34, 9, 168, 171, 129, 120, 161, 115, 196, 64, 113, 61, 44, 215, 188, 9, 110, 249, 243, 107, 227, 105, 200, 124, 12, 209, 21, 155, 67, 225, 240, 42, 107, 19, 212, 242, 236, 251, 14, 157, 232, 202, 93, 76, 125, 237, 173, 175, 178, 41, 145, 52, 43, 74, 132, 202, 20, 132, 237, 142, 122, 248, 31, 104, 105, 253, 168, 172, 70, 227, 115, 249, 227, 13, 130, 162, 112, 107, 196, 32, 9, 99, 50, 9, 83, 115, 137, 240, 117, 103, 17, 119, 57, 145, 199, 208, 62, 27, 115, 200, 196, 245, 43, 246, 175, 240, 26, 162, 92, 249, 194, 113, 161, 115, 196, 64, 227, 199, 17, 26, 50, 149, 36, 250, 241, 222, 56, 188, 127, 140, 131, 144, 167, 224, 18, 230, 61, 37, 113, 136, 156, 116, 104, 237, 140, 138, 121, 215, 140, 159, 38, 64, 106, 111, 177, 108, 51, 233, 152, 250, 233, 207, 138, 116, 61, 55, 89, 204, 6, 164, 2, 114, 128, 230, 199, 130, 136, 25, 207, 1, 130, 162, 112, 107, 196, 32, 231, 240, 248, 77, 6, 129, 29, 249, 243, 28, 141, 135, 139, 17, 85, 244, 103, 29, 81, 161, 133, 194, 0, 144, 134, 103, 244, 73, 88, 112, 104, 161, 161, 115, 196, 64, 125, 39, 23, 127, 48, 75, 104, 78, 54, 53, 177, 125, 33, 29, 42, 49, 173, 205, 5, 9, 225, 99, 169, 16, 177, 95, 186, 134, 218, 129, 179, 15, 219, 90, 103, 54, 188, 25, 90, 235, 144, 137, 45, 35, 66, 53, 45, 183, 232, 27, 20, 50, 91, 219, 194, 187, 55, 146, 113, 126, 233, 186, 161, 15, 163, 116, 104, 114, 2, 161, 118, 1, 163, 116, 120, 110, 140, 163, 102, 101, 101, 206, 0, 3, 200, 192, 162, 102, 118, 206, 0, 14, 249, 218, 163, 103, 101, 110, 172, 100, 101, 118, 110, 101, 116, 45, 118, 51, 56, 46, 48, 162, 103, 104, 196, 32, 254, 179, 108, 57, 16, 20, 57, 0, 195, 218, 85, 66, 202, 24, 54, 176, 15, 210, 248, 25, 89, 18, 87, 205, 35, 246, 4, 47, 152, 200, 54, 157, 162, 108, 118, 206, 0, 14, 253, 194, 166, 115, 101, 108, 107, 101, 121, 196, 32, 50, 18, 43, 43, 214, 61, 220, 83, 49, 150, 23, 165, 170, 83, 196, 177, 194, 111, 227, 220, 202, 242, 141, 54, 34, 181, 105, 119, 161, 64, 92, 134, 163, 115, 110, 100, 196, 32, 141, 146, 180, 137, 144, 1, 115, 160, 77, 250, 67, 89, 163, 102, 106, 106, 252, 234, 44, 66, 160, 93, 217, 193, 247, 62, 235, 165, 71, 128, 55, 233, 164, 116, 121, 112, 101, 166, 107, 101, 121, 114, 101, 103, 167, 118, 111, 116, 101, 102, 115, 116, 206, 0, 13, 187, 160, 166, 118, 111, 116, 101, 107, 100, 205, 39, 16, 167, 118, 111, 116, 101, 107, 101, 121, 196, 32, 112, 27, 215, 251, 145, 43, 7, 179, 8, 17, 255, 40, 29, 159, 238, 149, 99, 229, 128, 46, 32, 38, 137, 35, 25, 37, 143, 119, 250, 147, 30, 136, 167, 118, 111, 116, 101, 108, 115, 116, 206, 0, 15, 66, 64]);
 
-      const finMsigBlob = multisig.mergeMultisigTransactions([
+      const finMsigBlob = algosdk.mergeMultisigTransactions([
         new Uint8Array(twoAndThreeBlob),
         new Uint8Array(oneAndThreeBlob),
       ]);
-      const finMsigBlobTwo = multisig.mergeMultisigTransactions([
+      const finMsigBlobTwo = algosdk.mergeMultisigTransactions([
         new Uint8Array(oneAndThreeBlob),
         new Uint8Array(twoAndThreeBlob),
       ]);
@@ -278,9 +249,7 @@ describe('Multisig Functionality', () => {
       };
 
       stdPaymentTxn = algosdk.Transaction.from_obj_for_encoding(paymentTxnObj);
-      msigPaymentTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        paymentTxnObj
-      );
+      msigPaymentTxn = MultisigTransaction.from_obj_for_encoding(paymentTxnObj);
 
       const keyregTxnObj = {
         snd: Buffer.from(
@@ -292,9 +261,18 @@ describe('Multisig Functionality', () => {
         fv: 51,
         lv: 61,
         note: Buffer.from([123, 12, 200]),
-        gh: 'JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=',
-        votekey: '5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKE=',
-        selkey: 'oImqaSLjuZj63/bNSAjd+eAh5JROOJ6j1cY4eGaJGX4=',
+        gh: Buffer.from(
+          'JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=',
+          'base64'
+        ),
+        votekey: Buffer.from(
+          '5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKE=',
+          'base64'
+        ),
+        selkey: Buffer.from(
+          'oImqaSLjuZj63/bNSAjd+eAh5JROOJ6j1cY4eGaJGX4=',
+          'base64'
+        ),
         votefst: 123,
         votelst: 456,
         votekd: 1234,
@@ -303,9 +281,7 @@ describe('Multisig Functionality', () => {
       };
 
       stdKeyregTxn = algosdk.Transaction.from_obj_for_encoding(keyregTxnObj);
-      msigKeyregTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        keyregTxnObj
-      );
+      msigKeyregTxn = MultisigTransaction.from_obj_for_encoding(keyregTxnObj);
     });
 
     it('`estimateSize` method should match expected result', () => {
@@ -375,9 +351,18 @@ describe('Multisig Functionality', () => {
         fv: 51,
         lv: 61,
         note: Buffer.from([123, 12, 200]),
-        gh: 'JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=',
-        votekey: '5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKE=',
-        selkey: 'oImqaSLjuZj63/bNSAjd+eAh5JROOJ6j1cY4eGaJGX4=',
+        gh: Buffer.from(
+          'JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=',
+          'base64'
+        ),
+        votekey: Buffer.from(
+          '5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKE=',
+          'base64'
+        ),
+        selkey: Buffer.from(
+          'oImqaSLjuZj63/bNSAjd+eAh5JROOJ6j1cY4eGaJGX4=',
+          'base64'
+        ),
         votefst: 123,
         votelst: 456,
         votekd: 1234,
@@ -385,33 +370,29 @@ describe('Multisig Functionality', () => {
         type: 'keyreg',
       };
 
-      msigPaymentTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        paymentTxnObj
-      );
-      msigKeyregTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        keyregTxnObj
-      );
+      msigPaymentTxn = MultisigTransaction.from_obj_for_encoding(paymentTxnObj);
+      msigKeyregTxn = MultisigTransaction.from_obj_for_encoding(keyregTxnObj);
     });
 
     it('error should be thrown when attempting to add a lease to a transaction', () => {
       assert.throws(
         msigPaymentTxn.addLease,
-        (err) => err.message === multisig.MULTISIG_NO_MUTATE_ERROR_MSG
+        (err) => err.message === MULTISIG_NO_MUTATE_ERROR_MSG
       );
       assert.throws(
         msigKeyregTxn.addLease,
-        (err) => err.message === multisig.MULTISIG_NO_MUTATE_ERROR_MSG
+        (err) => err.message === MULTISIG_NO_MUTATE_ERROR_MSG
       );
     });
 
     it('error should be thrown when attempting to add a rekey to a transaction', () => {
       assert.throws(
         msigPaymentTxn.addRekey,
-        (err) => err.message === multisig.MULTISIG_NO_MUTATE_ERROR_MSG
+        (err) => err.message === MULTISIG_NO_MUTATE_ERROR_MSG
       );
       assert.throws(
         msigKeyregTxn.addRekey,
-        (err) => err.message === multisig.MULTISIG_NO_MUTATE_ERROR_MSG
+        (err) => err.message === MULTISIG_NO_MUTATE_ERROR_MSG
       );
     });
   });
@@ -461,9 +442,18 @@ describe('Multisig Functionality', () => {
         fv: 51,
         lv: 61,
         note: Buffer.from([123, 12, 200]),
-        gh: 'JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=',
-        votekey: '5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKE=',
-        selkey: 'oImqaSLjuZj63/bNSAjd+eAh5JROOJ6j1cY4eGaJGX4=',
+        gh: Buffer.from(
+          'JgsgCaCTqIaLeVhyL6XlRu3n7Rfk2FxMeK+wRSaQ7dI=',
+          'base64'
+        ),
+        votekey: Buffer.from(
+          '5/D4TQaBHfnzHI2HixFV9GcdUaGFwgCQhmf0SVhwaKE=',
+          'base64'
+        ),
+        selkey: Buffer.from(
+          'oImqaSLjuZj63/bNSAjd+eAh5JROOJ6j1cY4eGaJGX4=',
+          'base64'
+        ),
         votefst: 123,
         votelst: 456,
         votekd: 1234,
@@ -471,22 +461,18 @@ describe('Multisig Functionality', () => {
         type: 'keyreg',
       };
 
-      msigPaymentTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        paymentTxnObj
-      );
-      msigKeyregTxn = multisig.MultisigTransaction.from_obj_for_encoding(
-        keyregTxnObj
-      );
+      msigPaymentTxn = MultisigTransaction.from_obj_for_encoding(paymentTxnObj);
+      msigKeyregTxn = MultisigTransaction.from_obj_for_encoding(keyregTxnObj);
     });
 
     it('signTxn method should throw an error', () => {
       assert.throws(
         msigPaymentTxn.signTxn,
-        (err) => err.message === multisig.MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG
+        (err) => err.message === MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG
       );
       assert.throws(
         msigKeyregTxn.signTxn,
-        (err) => err.message === multisig.MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG
+        (err) => err.message === MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG
       );
     });
   });