{"version":3,"sources":["../../../../src/transactions/transactionBuilder/miniprogram.ts"],"sourcesContent":["// Copyright © Endless\n// Copyright © Aptos Foundation\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * This file handles the transaction creation lifecycle.\n * It holds different operations to generate a transaction payload, a raw transaction,\n * and a signed transaction that can be simulated, signed and submitted to chain.\n */\nimport { EndlessConfig } from \"../../api/endlessConfig\";\nimport { AccountAddress, AccountAddressInput, Hex } from \"../../core\";\nimport { getInfo } from \"../../internal/account\";\nimport { getLedgerInfo } from \"../../internal/general\";\nimport { getGasPriceEstimation } from \"../../internal/transaction\";\nimport { NetworkToChainId } from \"../../utils/apiEndpoints\";\nimport { DEFAULT_MAX_GAS_AMOUNT, DEFAULT_TXN_EXP_SEC_FROM_NOW } from \"../../utils/const\";\nimport {\n  ChainId,\n  EntryFunction,\n  MultiSig,\n  MultiSigTransactionPayload,\n  RawTransaction,\n  Script,\n  TransactionPayloadEntryFunction,\n  TransactionPayloadMultiSig,\n  TransactionPayloadScript,\n} from \"../instances\";\nimport {\n  AnyRawTransaction,\n  AnyTransactionPayloadInstance,\n  EntryFunctionArgumentTypes,\n  InputGenerateMultiAgentRawTransactionArgs,\n  InputGenerateRawTransactionArgs,\n  InputGenerateSingleSignerRawTransactionArgs,\n  InputGenerateTransactionOptions,\n  InputScriptData,\n  InputMultiSigDataWithRemoteABI,\n  InputEntryFunctionDataWithRemoteABI,\n  InputGenerateTransactionPayloadDataWithRemoteABI,\n  InputGenerateTransactionPayloadDataWithABI,\n  InputEntryFunctionDataWithABI,\n  InputMultiSigDataWithABI,\n  FunctionABI,\n} from \"../types\";\nimport { convertArgument, fetchEntryFunctionAbi, standardizeTypeTags } from \"./remoteAbi\";\nimport { memoizeAsync } from \"../../utils/memoize\";\nimport { getFunctionParts, isScriptDataInput } from \"./helpers\";\nimport { SimpleTransaction } from \"../instances/simpleTransaction\";\nimport { MultiAgentTransaction } from \"../instances/multiAgentTransaction\";\n\n/**\n * We are defining function signatures, each with its specific input and output.\n * These are the possible function signature for our `generateTransactionPayload` function.\n * When we call our `generateTransactionPayload` function with the relevant type properties,\n * Typescript can infer the return type based on the appropriate function overload.\n */\nexport async function generateTransactionPayload(args: InputScriptData): Promise<TransactionPayloadScript>;\nexport async function generateTransactionPayload(\n  args: InputEntryFunctionDataWithRemoteABI,\n): Promise<TransactionPayloadEntryFunction>;\nexport async function generateTransactionPayload(\n  args: InputMultiSigDataWithRemoteABI,\n): Promise<TransactionPayloadMultiSig>;\n\n/**\n * Builds a transaction payload based on the data argument and returns\n * a transaction payload - TransactionPayloadScript | TransactionPayloadMultiSig | TransactionPayloadEntryFunction\n *\n * This uses the RemoteABI by default, and the remote ABI can be skipped by using generateTransactionPayloadWithABI\n *\n * @param args.data GenerateTransactionPayloadData\n *\n * @return TransactionPayload\n */\nexport async function generateTransactionPayload(\n  args: InputGenerateTransactionPayloadDataWithRemoteABI,\n): Promise<AnyTransactionPayloadInstance> {\n  if (isScriptDataInput(args)) {\n    return generateTransactionPayloadScript(args);\n  }\n  const { moduleAddress, moduleName, functionName } = getFunctionParts(args.function);\n\n  const functionAbi = await fetchAbi({\n    key: \"entry-function\",\n    moduleAddress,\n    moduleName,\n    functionName,\n    endlessConfig: args.endlessConfig,\n    abi: args.abi,\n    fetch: fetchEntryFunctionAbi,\n  });\n\n  // Fill in the ABI\n  return generateTransactionPayloadWithABI({ ...args, abi: functionAbi });\n}\n\nexport function generateTransactionPayloadWithABI(args: InputEntryFunctionDataWithABI): TransactionPayloadEntryFunction;\nexport function generateTransactionPayloadWithABI(args: InputMultiSigDataWithABI): TransactionPayloadMultiSig;\nexport function generateTransactionPayloadWithABI(\n  args: InputGenerateTransactionPayloadDataWithABI,\n): AnyTransactionPayloadInstance {\n  const functionAbi = args.abi;\n  const { moduleAddress, moduleName, functionName } = getFunctionParts(args.function);\n\n  // Ensure that all type arguments are typed properly\n  const typeArguments = standardizeTypeTags(args.typeArguments);\n\n  // Check the type argument count against the ABI\n  if (typeArguments.length !== functionAbi.typeParameters.length) {\n    throw new Error(\n      `Type argument count mismatch, expected ${functionAbi.typeParameters.length}, received ${typeArguments.length}`,\n    );\n  }\n\n  // Check all BCS types, and convert any non-BCS types\n  const functionArguments: Array<EntryFunctionArgumentTypes> = args.functionArguments.map((arg, i) =>\n    convertArgument(args.function, functionAbi, arg, i, typeArguments),\n  );\n\n  // Check that all arguments are accounted for\n  if (functionArguments.length !== functionAbi.parameters.length) {\n    throw new Error(\n      // eslint-disable-next-line max-len\n      `Too few arguments for '${moduleAddress}::${moduleName}::${functionName}', expected ${functionAbi.parameters.length} but got ${functionArguments.length}`,\n    );\n  }\n\n  // Generate entry function payload\n  const entryFunctionPayload = EntryFunction.build(\n    `${moduleAddress}::${moduleName}`,\n    functionName,\n    typeArguments,\n    functionArguments,\n  );\n\n  // Send it as multi sig if it's a multisig payload\n  if (\"multisigAddress\" in args) {\n    const multisigAddress = AccountAddress.from(args.multisigAddress);\n    return new TransactionPayloadMultiSig(\n      new MultiSig(multisigAddress, new MultiSigTransactionPayload(entryFunctionPayload)),\n    );\n  }\n\n  // Otherwise send as an entry function\n  return new TransactionPayloadEntryFunction(entryFunctionPayload);\n}\n\nfunction generateTransactionPayloadScript(args: InputScriptData) {\n  return new TransactionPayloadScript(\n    new Script(\n      Hex.fromHexInput(args.bytecode).toUint8Array(),\n      standardizeTypeTags(args.typeArguments),\n      args.functionArguments,\n    ),\n  );\n}\n\n/**\n * Generates a raw transaction\n *\n * @param args.endlessConfig EndlessConfig\n * @param args.sender The transaction's sender account address as a hex input\n * @param args.payload The transaction payload - can create by using generateTransactionPayload()\n *\n * @returns RawTransaction\n */\nexport async function generateRawTransaction(args: {\n  endlessConfig: EndlessConfig;\n  sender: AccountAddressInput;\n  payload: AnyTransactionPayloadInstance;\n  options?: InputGenerateTransactionOptions;\n  feePayerAddress?: AccountAddressInput;\n}): Promise<RawTransaction> {\n  const { endlessConfig, sender, payload, options, feePayerAddress } = args;\n\n  const getChainId = async () => {\n    if (NetworkToChainId[endlessConfig.network]) {\n      return { chainId: NetworkToChainId[endlessConfig.network] };\n    }\n    const info = await getLedgerInfo({ endlessConfig });\n    return { chainId: info.chain_id };\n  };\n\n  const getGasUnitPrice = async () => {\n    if (options?.gasUnitPrice) {\n      return { gasEstimate: options.gasUnitPrice };\n    }\n    const estimation = await getGasPriceEstimation({ endlessConfig });\n    return { gasEstimate: estimation.gas_estimate };\n  };\n\n  const getSequenceNumberForAny = async () => {\n    const getSequenceNumber = async () => {\n      if (options?.accountSequenceNumber !== undefined) {\n        return options.accountSequenceNumber;\n      }\n\n      try {\n        return (await getInfo({ endlessConfig, accountAddress: sender })).sequence_number;\n      } catch (error: any) {\n        if (\"status\" in error && error.status === 404) {\n          return 0;\n        }\n        throw error;\n      }\n    };\n\n    /**\n     * Check if is sponsored transaction to honor AIP-52\n     * {@link https://github.com/endless-foundation/AIPs/blob/main/aips/aip-52.md}\n     */\n    if (feePayerAddress && AccountAddress.from(feePayerAddress).equals(AccountAddress.ZERO)) {\n      // Handle sponsored transaction generation with the option that\n      // the main signer has not been created on chain\n      try {\n        // Check if main signer has been created on chain, if not assign sequence number 0\n        return await getSequenceNumber();\n      } catch (e: any) {\n        return 0;\n      }\n    } else {\n      return getSequenceNumber();\n    }\n  };\n  const [{ chainId }, { gasEstimate }, sequenceNumber] = await Promise.all([\n    getChainId(),\n    getGasUnitPrice(),\n    getSequenceNumberForAny(),\n  ]);\n\n  const { maxGasAmount, gasUnitPrice, expireTimestamp } = {\n    maxGasAmount: options?.maxGasAmount ? BigInt(options.maxGasAmount) : BigInt(DEFAULT_MAX_GAS_AMOUNT),\n    gasUnitPrice: options?.gasUnitPrice ?? BigInt(gasEstimate),\n    expireTimestamp: options?.expireTimestamp ?? BigInt(Math.floor(Date.now() / 1000) + DEFAULT_TXN_EXP_SEC_FROM_NOW),\n  };\n\n  return new RawTransaction(\n    AccountAddress.from(sender),\n    BigInt(sequenceNumber),\n    payload,\n    BigInt(maxGasAmount),\n    BigInt(gasUnitPrice),\n    BigInt(expireTimestamp),\n    new ChainId(chainId),\n  );\n}\n\n/**\n * We are defining function signatures, each with its specific input and output.\n * These are the possible function signature for our `generateTransaction` function.\n * When we call our `generateTransaction` function with the relevant type properties,\n * Typescript can infer the return type based on the appropriate function overload.\n */\nexport async function buildTransaction(args: InputGenerateSingleSignerRawTransactionArgs): Promise<SimpleTransaction>;\nexport async function buildTransaction(args: InputGenerateMultiAgentRawTransactionArgs): Promise<MultiAgentTransaction>;\n\n/**\n * Generates a transaction based on the provided arguments\n *\n * Note: we can start with one function to support all different payload/transaction types,\n * and if to complex to use, we could have function for each type\n *\n * @param args.endlessConfig EndlessConfig\n * @param args.sender The transaction's sender account address as a hex input\n * @param args.payload The transaction payload - can create by using generateTransactionPayload()\n * @param args.options optional. Transaction options object\n * @param args.secondarySignerAddresses optional. For when want to create a multi signers transaction\n * @param args.feePayerAddress optional. For when want to create a fee payer (aka sponsored) transaction\n *\n * @return An instance of a RawTransaction, plus optional secondary/fee payer addresses\n * ```\n * {\n *  rawTransaction: RawTransaction,\n *  secondarySignerAddresses? : Array<AccountAddress>,\n *  feePayerAddress?: AccountAddress\n * }\n * ```\n */\nexport async function buildTransaction(args: InputGenerateRawTransactionArgs): Promise<AnyRawTransaction> {\n  const { endlessConfig, sender, payload, options, feePayerAddress } = args;\n  // generate raw transaction\n  const rawTxn = await generateRawTransaction({\n    endlessConfig,\n    sender,\n    payload,\n    options,\n    feePayerAddress,\n  });\n\n  // if multi agent transaction\n  if (\"secondarySignerAddresses\" in args) {\n    const signers: Array<AccountAddress> =\n      args.secondarySignerAddresses?.map((signer) => AccountAddress.from(signer)) ?? [];\n\n    return new MultiAgentTransaction(\n      rawTxn,\n      signers,\n      args.feePayerAddress ? AccountAddress.from(args.feePayerAddress) : undefined,\n    );\n  }\n  // return the raw transaction\n  return new SimpleTransaction(rawTxn, args.feePayerAddress ? AccountAddress.from(args.feePayerAddress) : undefined);\n}\n\n/**\n * Fetches and caches ABIs with allowing for pass-through on provided ABIs\n * @param key\n * @param moduleAddress\n * @param moduleName\n * @param functionName\n * @param endlessConfig\n * @param abi\n * @param fetch\n */\nasync function fetchAbi<T extends FunctionABI>({\n  key,\n  moduleAddress,\n  moduleName,\n  functionName,\n  endlessConfig,\n  abi,\n  fetch,\n}: {\n  key: string;\n  moduleAddress: string;\n  moduleName: string;\n  functionName: string;\n  endlessConfig: EndlessConfig;\n  abi?: T;\n  fetch: (moduleAddress: string, moduleName: string, functionName: string, endlessConfig: EndlessConfig) => Promise<T>;\n}): Promise<T> {\n  if (abi !== undefined) {\n    return abi;\n  }\n\n  // We fetch the entry function ABI, and then pretend that we already had the ABI\n  return memoizeAsync(\n    async () => fetch(moduleAddress, moduleName, functionName, endlessConfig),\n    `${key}-${endlessConfig.network}-${moduleAddress}-${moduleName}-${functionName}`,\n    1000 * 60 * 5, // 5 minutes\n  )();\n}\n"],"mappings":"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","names":["generateTransactionPayload","args","isScriptDataInput","generateTransactionPayloadScript","moduleAddress","moduleName","functionName","getFunctionParts","functionAbi","fetchAbi","fetchEntryFunctionAbi","generateTransactionPayloadWithABI","typeArguments","standardizeTypeTags","functionArguments","arg","i","convertArgument","entryFunctionPayload","EntryFunction","multisigAddress","AccountAddress","TransactionPayloadMultiSig","MultiSig","MultiSigTransactionPayload","TransactionPayloadEntryFunction","TransactionPayloadScript","Script","Hex","generateRawTransaction","endlessConfig","sender","payload","options","feePayerAddress","getChainId","NetworkToChainId","getLedgerInfo","getGasUnitPrice","getGasPriceEstimation","getSequenceNumberForAny","getSequenceNumber","getInfo","error","chainId","gasEstimate","sequenceNumber","maxGasAmount","gasUnitPrice","expireTimestamp","RawTransaction","ChainId","buildTransaction","rawTxn","signers","signer","MultiAgentTransaction","SimpleTransaction","key","abi","fetch","memoizeAsync"]}