<commit_before>import * as fs from 'fs';

import {
  makeUnsignedSTXTokenTransfer,
  makeContractDeploy,
  makeContractCall,
  makeStandardSTXPostCondition,
  makeContractSTXPostCondition,
  makeStandardFungiblePostCondition,
  makeContractFungiblePostCondition,
  makeStandardNonFungiblePostCondition,
  makeContractNonFungiblePostCondition,
  estimateTransfer,
  broadcastTransaction,
  getNonce,
  TxBroadcastResult,
  TxBroadcastResultOk,
  TxBroadcastResultRejected,
  callReadOnlyFunction,
  sponsorTransaction,
  makeSTXTokenTransfer,
  makeUnsignedContractCall
} from '../src/builders';

import { deserializeTransaction } from '../src/transaction';

import { TokenTransferPayload } from '../src/payload';

import { BufferReader } from '../src/bufferReader';

import { createAssetInfo } from '../src/types';

import { SingleSigSpendingCondition } from '../src/authorization';

import {
  DEFAULT_CORE_NODE_API_URL,
  FungibleConditionCode,
  NonFungibleConditionCode,
  PostConditionMode,
  TxRejectedReason,
  AuthType,
  AddressHashMode,
  AnchorMode,
} from '../src/constants';

import { StacksTestnet, StacksMainnet } from '@stacks/network';

import { bufferCV, standardPrincipalCV, bufferCVFromString, serializeCV } from '../src/clarity';

import { ClarityAbi } from '../src/contract-abi';
import { createStacksPrivateKey, pubKeyfromPrivKey, publicKeyToString } from '../src/keys';
import { TransactionSigner } from '../src/signer';
import fetchMock from 'jest-fetch-mock';

beforeEach(() => {
  fetchMock.resetMocks();
  jest.resetModules();
});

test('Make STX token transfer with set tx fee', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 12345;
  const fee = 0;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  const transaction = await makeSTXTokenTransfer({
    recipient,
    amount,
    senderKey,
    fee,
    nonce,
    memo,
    anchorMode: AnchorMode.Any
  });

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '0000000001040015c31b8c1c11c515e244b75806bac48d1399c77500000000000000000000000000000000' +
    '00008b316d56e35b3b8d03ab3b9dbe05eb44d64c53e7ba3c468f9a78c82a13f2174c32facb0f29faeb2107' +
    '5ec933db935ebc28a8793cc60e14b8ee4ef05f52c94016030200000000000516df0ba3e79792be7be5e50a' +
    '370289accfc8c9e032000000000000303974657374206d656d6f0000000000000000000000000000000000' +
    '0000000000000000';

  expect(serialized).toBe(tx);
});

test('Make STX token transfer with fee estimate', async () => {
  const apiUrl = `${DEFAULT_CORE_NODE_API_URL}/v2/fees/transfer`;
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 12345;
  const estimateFeeRate = 1;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  fetchMock.mockOnce(`${estimateFeeRate}`);

  const transaction = await makeSTXTokenTransfer({
    recipient,
    amount,
    nonce,
    senderKey,
    memo,
    anchorMode: AnchorMode.Any
  });

  const fee = transaction.serialize().byteLength * estimateFeeRate;

  expect(transaction.auth.spendingCondition?.fee?.toString()).toEqual(fee.toString());

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '0000000001040015c31b8c1c11c515e244b75806bac48d1399c775000000000000000000000000000000b4' +
    '0001e5ac1152f6018fbfded102268b22086666150823d0ae57f4023bde058a7ff0b279076db25b358b8833' +
    '2efba7a8a75e7ccd08207af62d799e6eb8b0357ad55558030200000000000516df0ba3e79792be7be5e50a' +
    '370289accfc8c9e032000000000000303974657374206d656d6f0000000000000000000000000000000000' +
    '0000000000000000';

  expect(fetchMock.mock.calls.length).toEqual(1);
  expect(fetchMock.mock.calls[0][0]).toEqual(apiUrl);
  expect(serialized).toBe(tx);
});

test('Make STX token transfer with testnet', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 12345;
  const fee = 0;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  const transaction = await makeSTXTokenTransfer({
    recipient,
    amount,
    senderKey,
    fee,
    nonce,
    network: new StacksTestnet(),
    memo: memo,
    anchorMode: AnchorMode.Any
  });

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '8080000000040015c31b8c1c11c515e244b75806bac48d1399c77500000000000000000000000000000000' +
    '00014199f63f7e010141a36a4624d032758f54e08ff03b24ed2667463eb405b4d81505631b32a1f13b5737' +
    '1f29a6095b81741b32b5864b178e3546ff2bfb3dc08682030200000000000516df0ba3e79792be7be5e50a' +
    '370289accfc8c9e032000000000000303974657374206d656d6f0000000000000000000000000000000000' +
    '0000000000000000';

  expect(serialized).toBe(tx);
});

test('Make STX token transfer with post conditions', async () => {
  const recipientAddress = 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159';
  const amount = 12345;
  const fee = 0;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  const postConditions = [
    makeStandardSTXPostCondition(
      recipientAddress,
      FungibleConditionCode.GreaterEqual,
      54321
    ),
  ];

  const transaction = await makeSTXTokenTransfer({
    recipient: standardPrincipalCV(recipientAddress),
    amount,
    senderKey,
    fee,
    nonce,
    memo,
    postConditions,
    anchorMode: AnchorMode.Any
  });

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '0000000001040015c31b8c1c11c515e244b75806bac48d1399c77500000000000000000000000000000000' +
    '0001601ceb46ef6988c8b226c80fef4051de6acf344dc67a9421d3e734a72ae310104b061e69cee5d9ee7a' +
    '6e1cef17f23b07d7fe4db5fcdb83de0d5f08043a06a36a030200000001000216df0ba3e79792be7be5e50a' +
    '370289accfc8c9e03203000000000000d431000516df0ba3e79792be7be5e50a370289accfc8c9e0320000' +
    '00000000303974657374206d656d6f00000000000000000000000000000000000000000000000000';

  expect(serialized).toBe(tx);
});

test('Make Multi-Sig STX token transfer', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 2500000;
  const fee = 0;
  const nonce = 0;
  const memo = 'test memo';

  const authType = AuthType.Standard;
  const addressHashMode = AddressHashMode.SerializeP2SH;

  const privKeyStrings = [
    '6d430bb91222408e7706c9001cfaeb91b08c2be6d5ac95779ab52c6b431950e001',
    '<KEY>',
    '<KEY>',
  ];
  const privKeys = privKeyStrings.map(createStacksPrivateKey);

  const pubKeys = privKeyStrings.map(pubKeyfromPrivKey);
  const pubKeyStrings = pubKeys.map(publicKeyToString);

  const transaction = await makeUnsignedSTXTokenTransfer({
    recipient,
    amount,
    fee,<commit_msg>test: make separate test for multiple signers<commit_after>import * as fs from 'fs';

import {
  makeUnsignedSTXTokenTransfer,
  makeContractDeploy,
  makeContractCall,
  makeStandardSTXPostCondition,
  makeContractSTXPostCondition,
  makeStandardFungiblePostCondition,
  makeContractFungiblePostCondition,
  makeStandardNonFungiblePostCondition,
  makeContractNonFungiblePostCondition,
  estimateTransfer,
  broadcastTransaction,
  getNonce,
  TxBroadcastResult,
  TxBroadcastResultOk,
  TxBroadcastResultRejected,
  callReadOnlyFunction,
  sponsorTransaction,
  makeSTXTokenTransfer,
  makeUnsignedContractCall
} from '../src/builders';

import { deserializeTransaction } from '../src/transaction';

import { TokenTransferPayload } from '../src/payload';

import { BufferReader } from '../src/bufferReader';

import { createAssetInfo } from '../src/types';

import { SingleSigSpendingCondition } from '../src/authorization';

import {
  DEFAULT_CORE_NODE_API_URL,
  FungibleConditionCode,
  NonFungibleConditionCode,
  PostConditionMode,
  TxRejectedReason,
  AuthType,
  AddressHashMode,
  AnchorMode,
} from '../src/constants';

import { StacksTestnet, StacksMainnet } from '@stacks/network';

import { bufferCV, standardPrincipalCV, bufferCVFromString, serializeCV } from '../src/clarity';

import { ClarityAbi } from '../src/contract-abi';
import { createStacksPrivateKey, pubKeyfromPrivKey, publicKeyToString } from '../src/keys';
import { TransactionSigner } from '../src/signer';
import fetchMock from 'jest-fetch-mock';

beforeEach(() => {
  fetchMock.resetMocks();
  jest.resetModules();
});

test('Make STX token transfer with set tx fee', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 12345;
  const fee = 0;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  const transaction = await makeSTXTokenTransfer({
    recipient,
    amount,
    senderKey,
    fee,
    nonce,
    memo,
    anchorMode: AnchorMode.Any
  });

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '0000000001040015c31b8c1c11c515e244b75806bac48d1399c77500000000000000000000000000000000' +
    '00008b316d56e35b3b8d03ab3b9dbe05eb44d64c53e7ba3c468f9a78c82a13f2174c32facb0f29faeb2107' +
    '5ec933db935ebc28a8793cc60e14b8ee4ef05f52c94016030200000000000516df0ba3e79792be7be5e50a' +
    '370289accfc8c9e032000000000000303974657374206d656d6f0000000000000000000000000000000000' +
    '0000000000000000';

  expect(serialized).toBe(tx);
});

test('Make STX token transfer with fee estimate', async () => {
  const apiUrl = `${DEFAULT_CORE_NODE_API_URL}/v2/fees/transfer`;
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 12345;
  const estimateFeeRate = 1;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  fetchMock.mockOnce(`${estimateFeeRate}`);

  const transaction = await makeSTXTokenTransfer({
    recipient,
    amount,
    nonce,
    senderKey,
    memo,
    anchorMode: AnchorMode.Any
  });

  const fee = transaction.serialize().byteLength * estimateFeeRate;

  expect(transaction.auth.spendingCondition?.fee?.toString()).toEqual(fee.toString());

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '0000000001040015c31b8c1c11c515e244b75806bac48d1399c775000000000000000000000000000000b4' +
    '0001e5ac1152f6018fbfded102268b22086666150823d0ae57f4023bde058a7ff0b279076db25b358b8833' +
    '2efba7a8a75e7ccd08207af62d799e6eb8b0357ad55558030200000000000516df0ba3e79792be7be5e50a' +
    '370289accfc8c9e032000000000000303974657374206d656d6f0000000000000000000000000000000000' +
    '0000000000000000';

  expect(fetchMock.mock.calls.length).toEqual(1);
  expect(fetchMock.mock.calls[0][0]).toEqual(apiUrl);
  expect(serialized).toBe(tx);
});

test('Make STX token transfer with testnet', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 12345;
  const fee = 0;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  const transaction = await makeSTXTokenTransfer({
    recipient,
    amount,
    senderKey,
    fee,
    nonce,
    network: new StacksTestnet(),
    memo: memo,
    anchorMode: AnchorMode.Any
  });

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '8080000000040015c31b8c1c11c515e244b75806bac48d1399c77500000000000000000000000000000000' +
    '00014199f63f7e010141a36a4624d032758f54e08ff03b24ed2667463eb405b4d81505631b32a1f13b5737' +
    '1f29a6095b81741b32b5864b178e3546ff2bfb3dc08682030200000000000516df0ba3e79792be7be5e50a' +
    '370289accfc8c9e032000000000000303974657374206d656d6f0000000000000000000000000000000000' +
    '0000000000000000';

  expect(serialized).toBe(tx);
});

test('Make STX token transfer with post conditions', async () => {
  const recipientAddress = 'SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159';
  const amount = 12345;
  const fee = 0;
  const nonce = 0;
  const senderKey = 'edf9aee84d9b7abc145504dde6726c64f369d37ee34ded868fabd876c26570bc01';
  const memo = 'test memo';

  const postConditions = [
    makeStandardSTXPostCondition(
      recipientAddress,
      FungibleConditionCode.GreaterEqual,
      54321
    ),
  ];

  const transaction = await makeSTXTokenTransfer({
    recipient: standardPrincipalCV(recipientAddress),
    amount,
    senderKey,
    fee,
    nonce,
    memo,
    postConditions,
    anchorMode: AnchorMode.Any
  });

  const serialized = transaction.serialize().toString('hex');

  const tx =
    '0000000001040015c31b8c1c11c515e244b75806bac48d1399c77500000000000000000000000000000000' +
    '0001601ceb46ef6988c8b226c80fef4051de6acf344dc67a9421d3e734a72ae310104b061e69cee5d9ee7a' +
    '6e1cef17f23b07d7fe4db5fcdb83de0d5f08043a06a36a030200000001000216df0ba3e79792be7be5e50a' +
    '370289accfc8c9e03203000000000000d431000516df0ba3e79792be7be5e50a370289accfc8c9e0320000' +
    '00000000303974657374206d656d6f00000000000000000000000000000000000000000000000000';

  expect(serialized).toBe(tx);
});

test('Make Multi-Sig STX token transfer', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 2500000;
  const fee = 0;
  const nonce = 0;
  const memo = 'test memo';

  const authType = AuthType.Standard;
  const addressHashMode = AddressHashMode.SerializeP2SH;

  const privKeyStrings = [
    '6d430bb91222408e7706c9001cfaeb91b08c2be6d5ac95779ab52c6b431950e001',
    '<KEY>',
    '<KEY>',
  ];
  const privKeys = privKeyStrings.map(createStacksPrivateKey);

  const pubKeys = privKeyStrings.map(pubKeyfromPrivKey);
  const pubKeyStrings = pubKeys.map(publicKeyToString);

  const transaction = await makeUnsignedSTXTokenTransfer({
    recipient,
    amount,
    fee,
    nonce,
    memo: memo,
    numSignatures: 2,
    publicKeys: pubKeyStrings,
    anchorMode: AnchorMode.Any
  });

  const serializedTx = transaction.serialize();

  const tx =
    '00000000010401a23ea89d6529ac48ac766f720e480beec7f1927300000000000000000000000000000000' +
    '000000000002030200000000000516df0ba3e79792be7be5e50a370289accfc8c9e03200000000002625a0' +
    '74657374206d656d6f00000000000000000000000000000000000000000000000000';

  expect(serializedTx.toString('hex')).toBe(tx);

  const bufferReader = new BufferReader(serializedTx);
  const deserializedTx = deserializeTransaction(bufferReader);

  expect(deserializedTx.auth.authType).toBe(authType);

  expect(deserializedTx.auth.spendingCondition!.hashMode).toBe(addressHashMode);
  expect(deserializedTx.auth.spendingCondition!.nonce.toString()).toBe(nonce.toString());
  expect(deserializedTx.auth.spendingCondition!.fee.toString()).toBe(fee.toString());
  expect(deserializedTx.auth.spendingCondition!.signer).toEqual(
    'a23ea89d6529ac48ac766f720e480beec7f19273'
  );
  const deserializedPayload = deserializedTx.payload as TokenTransferPayload;
  expect(deserializedPayload.amount.toString()).toBe(amount.toString());

  const signer = new TransactionSigner(deserializedTx);
  signer.signOrigin(privKeys[0]);
  signer.signOrigin(privKeys[1]);
  signer.appendOrigin(pubKeys[2]);

  const serializedSignedTx = deserializedTx.serialize();
  const signedTx =
    '00000000010401a23ea89d6529ac48ac766f720e480beec7f19273000000000000000000000000000000000' +
    '00000030200dc8061e63a8ed7ca4712c257299b4bdc3938e34ccc01ce979dd74e5483c4f971053a12680cbf' +
    'bea87976543a94500314c9a1eaf33986aef97821eb65fb0c604202018ff7d2d8cd4e43498912bfc2c30be1f' +
    'd58bef8d819e1371a0f5afa5e4b58ff6e498bd67b58c32bf670f0d8bcb399fa141e5c5cc21e57d30a091395' +
    'c95c9e05580003661ec7479330bf1ef7a4c9d1816f089666a112e72d671048e5424fc528ca5153000203020' +
    '0000000000516df0ba3e79792be7be5e50a370289accfc8c9e03200000000002625a074657374206d656d6f' +
    '00000000000000000000000000000000000000000000000000';

  expect(serializedSignedTx.toString('hex')).toBe(signedTx);
});

test('Make Multi-Sig STX token transfer with two transaction signers', async () => {
  const recipient = standardPrincipalCV('SP3FGQ8Z7JY9BWYZ5WM53E0M9NK7WHJF0691NZ159');
  const amount = 2500000;
  const fee = 0;
  const nonce = 0;
  const memo = 'test memo';

  const authType = AuthType.Standard;
  const addressHashMode = AddressHashMode.SerializeP2SH;

  const privKeyStrings = [
    '6d430bb91222408e7706c9001cfaeb91b08c2be6d5ac95779ab52c6b431950e001',
    '<KEY>',
    '<KEY>',
  ];
  const privKeys = privKeyStrings.map(createStacksPrivateKey);

  const pubKeys = privKeyStrings.map(pubKeyfromPrivKey);
  const pubKeyStrings = pubKeys.map(publicKeyToString);

  const transaction = await makeUnsignedSTXTokenTransfer({
    recipient,
    amount,
    fee,
{'fraction_non_alphanumeric': 0.08961038961038961, 'fraction_numerical': 0.21829988193624558, 'mean_word_length': 5.861482381530984, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 22, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 59, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1550475', 'n_tokens_mistral': 8507, 'n_tokens_neox': 6121, 'n_words': 839}