All files / src/transactions/builders make-contract-deploy.ts

80.95% Statements 34/42
57.14% Branches 8/14
50% Functions 1/2
80.48% Lines 33/41

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 1079x 9x 9x   9x 9x         9x         9x 9x 9x 9x   9x 9x                     9x     2x               2x   2x     2x 2x   2x   2x             2x 1x   1x     2x 2x           2x 2x                   2x         2x                   2x 2x 2x     2x    
import { TransactionVersion } from 'micro-stacks/common';
import { StacksMainnet } from 'micro-stacks/network';
import { AddressHashMode, PostConditionMode } from '../common/constants';
import { PostCondition } from '../postcondition';
import { StacksTransaction } from '../transaction';
import { createSmartContractPayload } from '../payload';
import {
  createStacksPrivateKey,
  getPublicKeyFromStacksPrivateKey,
  publicKeyToString,
} from '../keys';
import {
  createSingleSigSpendingCondition,
  createSponsoredAuth,
  createStandardAuth,
} from '../authorization';
import { createLPList } from '../types';
import { publicKeyToStxAddress, StacksNetworkVersion } from 'micro-stacks/crypto';
import { TransactionSigner } from '../signer';
import { ContractDeployOptions } from './types';
import { getNonce } from '../fetchers/get-nonce';
import { estimateContractDeploy } from '../fetchers/estimate-contract-deploy';
 
/**
 * Generates a Clarity smart contract deploy transaction
 *
 * @param  {ContractDeployOptions} txOptions - an options object for the contract deploy
 *
 * Returns a signed Stacks smart contract deploy transaction.
 *
 * @return {StacksTransaction}
 */
export async function makeContractDeploy(
  txOptions: ContractDeployOptions
): Promise<StacksTransaction> {
  const defaultOptions = {
    fee: BigInt(0),
    nonce: BigInt(0),
    network: new StacksMainnet(),
    postConditionMode: PostConditionMode.Deny,
    sponsored: false,
  };
 
  const options = Object.assign(defaultOptions, txOptions);
 
  const payload = createSmartContractPayload(options.contractName, options.codeBody);
 
  const addressHashMode = AddressHashMode.SerializeP2PKH;
  const privKey = createStacksPrivateKey(options.senderKey);
  const pubKey = getPublicKeyFromStacksPrivateKey(privKey);
 
  let authorization = null;
 
  const spendingCondition = createSingleSigSpendingCondition(
    addressHashMode,
    publicKeyToString(pubKey),
    options.nonce,
    options.fee
  );
 
  if (options.sponsored) {
    authorization = createSponsoredAuth(spendingCondition);
  } else {
    authorization = createStandardAuth(spendingCondition);
  }
 
  const postConditions: PostCondition[] = [];
  Iif (options.postConditions && options.postConditions.length > 0) {
    options.postConditions.forEach(postCondition => {
      postConditions.push(postCondition);
    });
  }
 
  const lpPostConditions = createLPList(postConditions);
  const transaction = new StacksTransaction(
    options.network.version,
    authorization,
    payload,
    lpPostConditions,
    options.postConditionMode,
    options.anchorMode,
    options.network.chainId
  );
 
  Iif (txOptions.fee === undefined || txOptions.fee === null) {
    const txFee = await estimateContractDeploy(transaction, options.network);
    transaction.setFee(txFee);
  }
 
  Iif (txOptions.nonce === undefined || txOptions.nonce === null) {
    const addressVersion =
      options.network.version === TransactionVersion.Mainnet
        ? StacksNetworkVersion.mainnetP2PKH
        : StacksNetworkVersion.testnetP2PKH;
    const senderAddress = publicKeyToStxAddress(publicKeyToString(pubKey), addressVersion);
    const txNonce = await getNonce(senderAddress, options.network);
    transaction.setNonce(txNonce);
  }
 
  if (options.senderKey) {
    const signer = new TransactionSigner(transaction);
    await signer.signOrigin(privKey);
  }
 
  return transaction;
}