@algorandfoundation/algokit-utils 10.0.0-alpha.43 → 10.0.0-alpha.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/account-manager.js +2 -2
- package/account-manager.js.map +1 -1
- package/account-manager.mjs +2 -2
- package/account-manager.mjs.map +1 -1
- package/algorand-client-transaction-creator.d.ts +5 -5
- package/algorand-client-transaction-sender.d.ts +5 -5
- package/algorand-client-transaction-sender.js +17 -17
- package/algorand-client-transaction-sender.js.map +1 -1
- package/algorand-client-transaction-sender.mjs +17 -17
- package/algorand-client-transaction-sender.mjs.map +1 -1
- package/app-client.d.ts +7 -7
- package/app-deployer.js +9 -9
- package/app-deployer.js.map +1 -1
- package/app-deployer.mjs +9 -9
- package/app-deployer.mjs.map +1 -1
- package/app-factory.d.ts +8 -8
- package/package.json +1 -1
- package/packages/crypto/src/index.js +7 -5
- package/packages/crypto/src/index.js.map +1 -1
- package/packages/crypto/src/index.mjs +7 -5
- package/packages/crypto/src/index.mjs.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"algorand-client-transaction-sender.mjs","names":[],"sources":["../src/algorand-client-transaction-sender.ts"],"sourcesContent":["import { ABIMethod } from '@algorandfoundation/algokit-abi'\nimport { ReadableAddress, getAddress, getApplicationAddress } from '@algorandfoundation/algokit-common'\nimport { Transaction } from '@algorandfoundation/algokit-transact'\nimport { Buffer } from 'buffer'\nimport { SendAppCreateTransactionResult, SendAppTransactionResult, SendAppUpdateTransactionResult } from './app'\nimport { AppManager } from './app-manager'\nimport { AssetManager } from './asset-manager'\nimport {\n AppCallMethodCall,\n AppCallParams,\n AppCreateMethodCall,\n AppCreateParams,\n AppDeleteMethodCall,\n AppDeleteParams,\n AppUpdateMethodCall,\n AppUpdateParams,\n AssetCreateParams,\n AssetOptOutParams,\n TransactionComposer,\n TransactionComposerConfig,\n} from './composer'\nimport { Config } from './config'\nimport { SendParams, SendSingleTransactionResult } from './transaction/types'\nimport { asJson, defaultJsonValueReplacer } from './util'\n\nconst getMethodCallForLog = ({ method, args }: { method: ABIMethod; args?: unknown[] }) => {\n return `${method.name}(${(args ?? []).map((a) =>\n typeof a === 'object'\n ? asJson(a, (k, v) => {\n const newV = defaultJsonValueReplacer(k, v)\n return newV instanceof Uint8Array ? Buffer.from(newV).toString('base64') : newV\n })\n : a,\n )})`\n}\n\n/** Orchestrates sending transactions for `AlgorandClient`. */\nexport class AlgorandClientTransactionSender {\n private _newGroup: () => TransactionComposer\n private _assetManager: AssetManager\n private _appManager: AppManager\n\n /**\n * Creates a new `AlgorandClientSender`\n * @param newGroup A lambda that starts a new `TransactionComposer` transaction group\n * @param assetManager An `AssetManager` instance\n * @param appManager An `AppManager` instance\n * @example\n * ```typescript\n * const transactionSender = new AlgorandClientTransactionSender(() => new TransactionComposer(), assetManager, appManager)\n * ```\n */\n constructor(newGroup: (config?: TransactionComposerConfig) => TransactionComposer, assetManager: AssetManager, appManager: AppManager) {\n this._newGroup = newGroup\n this._assetManager = assetManager\n this._appManager = appManager\n }\n\n /**\n * Start a new `TransactionComposer` transaction group\n * @returns A new instance of `TransactionComposer`.\n * @example\n * const composer = AlgorandClient.mainNet().send.newGroup();\n * const result = await composer.addTransaction(payment).send()\n */\n newGroup() {\n return this._newGroup()\n }\n\n private _send<T>(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendSingleTransactionResult> {\n return async (params) => {\n const composer = this._newGroup()\n\n // Ensure `this` is properly populated\n c(composer).apply(composer, [params])\n\n if (log?.preLog) {\n const transaction = (await composer.build()).transactions.at(-1)!.txn\n Config.getLogger(params?.suppressLog).debug(log.preLog(params, transaction))\n }\n\n const rawResult = await composer.send(params)\n const result = {\n // Last item covers when a group is created by an app call with ABI transaction parameters\n transaction: rawResult.transactions.at(-1)!,\n confirmation: rawResult.confirmations.at(-1)!,\n txId: rawResult.txIds.at(-1)!,\n ...rawResult,\n }\n\n if (log?.postLog) {\n Config.getLogger(params?.suppressLog).debug(log.postLog(params, result))\n }\n\n return result\n }\n }\n\n private _sendAppCall<\n T extends\n | AppCreateParams\n | AppUpdateParams\n | AppCallParams\n | AppDeleteParams\n | AppCreateMethodCall\n | AppUpdateMethodCall\n | AppCallMethodCall\n | AppDeleteMethodCall,\n >(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendAppTransactionResult> {\n return async (params) => {\n const result = await this._send(c, log)(params)\n\n return { ...result, return: AppManager.getABIReturn(result.confirmation, 'method' in params ? params.method : undefined) }\n }\n }\n\n private _sendAppUpdateCall<T extends AppCreateParams | AppUpdateParams | AppCreateMethodCall | AppUpdateMethodCall>(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendAppUpdateTransactionResult> {\n return async (params) => {\n const result = await this._sendAppCall(c, log)(params)\n\n const compiledApproval =\n typeof params.approvalProgram === 'string' ? this._appManager.getCompilationResult(params.approvalProgram) : undefined\n const compiledClear =\n typeof params.clearStateProgram === 'string' ? this._appManager.getCompilationResult(params.clearStateProgram) : undefined\n\n return { ...result, compiledApproval, compiledClear }\n }\n }\n\n private _sendAppCreateCall<T extends AppCreateParams | AppCreateMethodCall>(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendAppCreateTransactionResult> {\n return async (params) => {\n const result = await this._sendAppUpdateCall(c, log)(params)\n\n return {\n ...result,\n appId: BigInt(result.confirmation.appId!),\n appAddress: getApplicationAddress(result.confirmation.appId!),\n }\n }\n }\n\n /**\n * Send a payment transaction to transfer Algo between accounts.\n * @param params The parameters for the payment transaction\n * @example Basic example\n * {@includeCode ./algorand-client.spec.ts#example-send-payment}\n * @example Advanced example\n * ```typescript\n * const result = await algorand.send.payment({\n * amount: (4).algo(),\n * receiver: 'RECEIVERADDRESS',\n * sender: 'SENDERADDRESS',\n * closeRemainderTo: 'CLOSEREMAINDERTOADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // Use this with caution, it's generally better to use algorand.account.rekeyAccount\n * rekeyTo: 'REKEYTOADDRESS',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @see [Full working example](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/algorand-client.spec.ts)\n * @returns The result of the payment transaction and the transaction that was sent\n */\n payment = this._send((c) => c.addPayment, {\n preLog: (params, transaction) =>\n `Sending ${params.amount.microAlgo} µALGO from ${params.sender} to ${params.receiver} via transaction ${transaction.txId()}`,\n })\n /**\n * Create a new Algorand Standard Asset.\n *\n * The account that sends this transaction will automatically be\n * opted in to the asset and will hold all units after creation.\n *\n * @param params The parameters for the asset creation transaction\n *\n * @example Basic example\n * {@includeCode ./algorand-client.spec.ts#example-send-asset-create}\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetCreate({\n * sender: 'CREATORADDRESS',\n * total: 100n,\n * decimals: 2,\n * assetName: 'asset',\n * unitName: 'unit',\n * url: 'url',\n * metadataHash: 'metadataHash',\n * defaultFrozen: false,\n * manager: 'MANAGERADDRESS',\n * reserve: 'RESERVEADDRESS',\n * freeze: 'FREEZEADDRESS',\n * clawback: 'CLAWBACKADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @see [Full working example](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/algorand-client.spec.ts)\n * @returns The result of the asset create transaction and the transaction that was sent\n */\n assetCreate = async (params: AssetCreateParams & SendParams) => {\n const result = await this._send((c) => c.addAssetCreate, {\n postLog: (params, result) =>\n `Created asset${params.assetName ? ` ${params.assetName}` : ''}${params.unitName ? ` (${params.unitName})` : ''} with ${params.total} units and ${params.decimals ?? 0} decimals created by ${params.sender} with ID ${result.confirmation.assetId} via transaction ${result.txIds.at(-1)}`,\n })(params)\n return { ...result, assetId: BigInt(result.confirmation.assetId ?? 0) }\n }\n /**\n * Configure an existing Algorand Standard Asset.\n *\n * **Note:** The manager, reserve, freeze, and clawback addresses\n * are immutably empty if they are not set. If manager is not set then\n * all fields are immutable from that point forward.\n *\n * @param params The parameters for the asset config transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetConfig({ sender: \"MANAGERADDRESS\", assetId: 123456n, manager: \"MANAGERADDRESS\" })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetConfig({\n * sender: 'MANAGERADDRESS',\n * assetId: 123456n,\n * manager: 'MANAGERADDRESS',\n * reserve: 'RESERVEADDRESS',\n * freeze: 'FREEZEADDRESS',\n * clawback: 'CLAWBACKADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset config transaction and the transaction that was sent\n */\n assetConfig = this._send((c) => c.addAssetConfig, {\n preLog: (params, transaction) => `Configuring asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Freeze or unfreeze an Algorand Standard Asset for an account.\n *\n * @param params The parameters for the asset freeze transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetFreeze({ sender: \"MANAGERADDRESS\", assetId: 123456n, account: \"ACCOUNTADDRESS\", frozen: true })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetFreeze({\n * sender: 'MANAGERADDRESS',\n * assetId: 123456n,\n * account: 'ACCOUNTADDRESS',\n * frozen: true,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset freeze transaction and the transaction that was sent\n */\n assetFreeze = this._send((c) => c.addAssetFreeze, {\n preLog: (params, transaction) => `Freezing asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Destroys an Algorand Standard Asset.\n *\n * Created assets can be destroyed only by the asset manager account.\n * All of the assets must be owned by the creator of the asset before\n * the asset can be deleted.\n *\n * @param params The parameters for the asset destroy transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetDestroy({ sender: \"MANAGERADDRESS\", assetId: 123456n })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetDestroy({\n * sender: 'MANAGERADDRESS',\n * assetId: 123456n,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset destroy transaction and the transaction that was sent\n */\n assetDestroy = this._send((c) => c.addAssetDestroy, {\n preLog: (params, transaction) => `Destroying asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Transfer an Algorand Standard Asset.\n *\n * @param params The parameters for the asset transfer transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetTransfer({ sender: \"HOLDERADDRESS\", assetId: 123456n, amount: 1n, receiver: \"RECEIVERADDRESS\" })\n * ```\n * @example Advanced example (with clawback)\n * ```typescript\n * await algorand.send.assetTransfer({\n * sender: 'CLAWBACKADDRESS',\n * assetId: 123456n,\n * amount: 1n,\n * receiver: 'RECEIVERADDRESS',\n * clawbackTarget: 'HOLDERADDRESS',\n * // This field needs to be used with caution\n * closeAssetTo: 'ADDRESSTOCLOSETO'\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset transfer transaction and the transaction that was sent\n */\n assetTransfer = this._send((c) => c.addAssetTransfer, {\n preLog: (params, transaction) =>\n `Transferring ${params.amount} units of asset with ID ${params.assetId} from ${params.sender} to ${params.receiver} via transaction ${transaction.txId()}`,\n })\n /**\n * Opt an account into an Algorand Standard Asset.\n *\n * @param params The parameters for the asset opt-in transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetOptIn({ sender: \"SENDERADDRESS\", assetId: 123456n })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetOptIn({\n * sender: 'SENDERADDRESS',\n * assetId: 123456n,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset opt-in transaction and the transaction that was sent\n */\n assetOptIn = this._send((c) => c.addAssetOptIn, {\n preLog: (params, transaction) => `Opting in ${params.sender} to asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Opt an account out of an Algorand Standard Asset.\n *\n * *Note:* If the account has a balance of the asset,\n * it will not be able to opt-out unless `ensureZeroBalance`\n * is set to `false` (but then the account will lose the assets).\n *\n * @param params The parameters for the asset opt-out transaction\n *\n * @example Basic example (without creator, will be retrieved from algod)\n * ```typescript\n * await algorand.send.assetOptOut({ sender: \"SENDERADDRESS\", assetId: 123456n, ensureZeroBalance: true })\n * ```\n * @example Basic example (with creator)\n * ```typescript\n * await algorand.send.assetOptOut({ sender: \"SENDERADDRESS\", creator: \"CREATORADDRESS\", assetId: 123456n, ensureZeroBalance: true })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetOptOut({\n * sender: 'SENDERADDRESS',\n * assetId: 123456n,\n * creator: 'CREATORADDRESS',\n * ensureZeroBalance: true,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset opt-out transaction and the transaction that was sent\n */\n assetOptOut = async (\n params: Omit<AssetOptOutParams, 'creator'> & {\n /** Optional asset creator account address; if not specified it will be retrieved from algod */\n creator?: ReadableAddress\n /** Whether or not to check if the account has a zero balance first or not.\n *\n * If this is set to `true` and the account has an asset balance it will throw an error.\n *\n * If this is set to `false` and the account has an asset balance it will lose those assets to the asset creator.\n */\n ensureZeroBalance: boolean\n } & SendParams,\n ) => {\n if (params.ensureZeroBalance) {\n let balance = 0n\n try {\n const accountAssetInfo = await this._assetManager.getAccountInformation(getAddress(params.sender), params.assetId)\n balance = accountAssetInfo.balance\n } catch {\n throw new Error(`Account ${params.sender} is not opted-in to Asset ${params.assetId}; can't opt-out.`)\n }\n if (balance !== 0n) {\n throw new Error(`Account ${params.sender} does not have a zero balance for Asset ${params.assetId}; can't opt-out.`)\n }\n }\n\n params.creator = params.creator ?? (await this._assetManager.getById(params.assetId)).creator\n\n return await this._send((c) => c.addAssetOptOut, {\n preLog: (params, transaction) =>\n `Opting ${params.sender} out of asset with ID ${params.assetId} to creator ${params.creator} via transaction ${transaction.txId()}`,\n })(params as AssetOptOutParams & SendParams)\n }\n /**\n * Create a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app creation transaction\n * @example Basic example\n * ```typescript\n * const result = await algorand.send.appCreate({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE' })\n * const createdAppId = result.appId\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appCreate({\n * sender: 'CREATORADDRESS',\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * schema: {\n * globalInts: 1,\n * globalByteSlices: 2,\n * localInts: 3,\n * localByteSlices: 4\n * },\n * extraProgramPages: 1,\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app create transaction and the transaction that was sent\n */\n appCreate = this._sendAppCreateCall((c) => c.addAppCreate, {\n postLog: (params, result) =>\n `App created by ${params.sender} with ID ${result.confirmation.appId} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Update a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app update transaction\n * @example Basic example\n * ```typescript\n * await algorand.send.appUpdate({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE' })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appUpdate({\n * sender: 'CREATORADDRESS',\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * onComplete: OnApplicationComplete.UpdateApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app update transaction and the transaction that was sent\n */\n appUpdate = this._sendAppUpdateCall((c) => c.addAppUpdate, {\n postLog: (params, result) =>\n `App ${params.appId} updated ${params.args ? ` with ${params.args.map((a) => Buffer.from(a).toString('base64'))}` : ''} by ${params.sender} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Delete a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app deletion transaction\n * @example Basic example\n * ```typescript\n * await algorand.send.appDelete({ sender: 'CREATORADDRESS' })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appDelete({\n * sender: 'CREATORADDRESS',\n * onComplete: OnApplicationComplete.DeleteApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app delete transaction and the transaction that was sent\n */\n appDelete = this._sendAppCall((c) => c.addAppDelete, {\n postLog: (params, result) =>\n `App ${params.appId} deleted ${params.args ? ` with ${params.args.map((a) => Buffer.from(a).toString('base64'))}` : ''} by ${params.sender} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Call a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app call transaction\n * @example Basic example\n * ```typescript\n * await algorand.send.appCall({ sender: 'CREATORADDRESS' })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appCall({\n * sender: 'CREATORADDRESS',\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app call transaction and the transaction that was sent\n */\n appCall = this._sendAppCall((c) => c.addAppCall, {\n postLog: (params, result) =>\n `App ${params.appId} called ${params.args ? ` with ${params.args.map((a) => Buffer.from(a).toString('base64'))}` : ''} by ${params.sender} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Create a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app creation transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * const result = await algorand.send.appCreateMethodCall({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE', method: method, args: [\"arg1_value\"] })\n * const createdAppId = result.appId\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appCreateMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * schema: {\n * globalInts: 1,\n * globalByteSlices: 2,\n * localInts: 3,\n * localByteSlices: 4\n * },\n * extraProgramPages: 1,\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method create transaction and the transaction that was sent\n */\n appCreateMethodCall = this._sendAppCreateCall((c) => c.addAppCreateMethodCall, {\n postLog: (params, result) =>\n `App created by ${params.sender} with ID ${result.confirmation.appId} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Update a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app update transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appUpdateMethodCall({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE', method: method, args: [\"arg1_value\"] })\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appUpdateMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * onComplete: OnApplicationComplete.UpdateApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method update transaction and the transaction that was sent\n */\n appUpdateMethodCall = this._sendAppUpdateCall((c) => c.addAppUpdateMethodCall, {\n postLog: (params, result) =>\n `App ${params.appId} updated with ${getMethodCallForLog(params)} by ${params.sender} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Delete a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app deletion transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appDeleteMethodCall({ sender: 'CREATORADDRESS', method: method, args: [\"arg1_value\"] })\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appDeleteMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * onComplete: OnApplicationComplete.DeleteApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method delete transaction and the transaction that was sent\n */\n appDeleteMethodCall = this._sendAppCall((c) => c.addAppDeleteMethodCall, {\n postLog: (params, result) =>\n `App ${params.appId} deleted with ${getMethodCallForLog(params)} by ${params.sender} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Call a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app call transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appCallMethodCall({ sender: 'CREATORADDRESS', method: method, args: [\"arg1_value\"] })\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appCallMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method call transaction and the transaction that was sent\n */\n appCallMethodCall = this._sendAppCall((c) => c.addAppCallMethodCall, {\n postLog: (params, result) =>\n `App ${params.appId} called with ${getMethodCallForLog(params)} by ${params.sender} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Register an online key.\n * @param params The parameters for the key registration transaction\n * @example Basic example\n * ```typescript\n * const result = await algorand.send.onlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * voteKey: Uint8Array.from(Buffer.from(\"voteKeyBase64\", 'base64')),\n * selectionKey: Uint8Array.from(Buffer.from(\"selectionKeyBase64\", 'base64')),\n * stateProofKey: Uint8Array.from(Buffer.from(\"stateProofKeyBase64\", 'base64')),\n * voteFirst: 1n,\n * voteLast: 1000n,\n * voteKeyDilution: 1n,\n * })\n * ```\n * @example Advanced example\n * ```typescript\n * const result = await algorand.send.onlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * voteKey: Uint8Array.from(Buffer.from(\"voteKeyBase64\", 'base64')),\n * selectionKey: Uint8Array.from(Buffer.from(\"selectionKeyBase64\", 'base64')),\n * stateProofKey: Uint8Array.from(Buffer.from(\"stateProofKeyBase64\", 'base64')),\n * voteFirst: 1n,\n * voteLast: 1000n,\n * voteKeyDilution: 1n,\n * lease: 'lease',\n * note: 'note',\n * // Use this with caution, it's generally better to use algorand.account.rekeyAccount\n * rekeyTo: 'REKEYTOADDRESS',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * })\n * ```\n * @returns The result of the online key registration transaction and the transaction that was sent\n */\n onlineKeyRegistration = this._send((c) => c.addOnlineKeyRegistration, {\n preLog: (params, transaction) => `Registering online key for ${params.sender} via transaction ${transaction.txId()}`,\n })\n\n /**\n * Register an offline key.\n * @param params The parameters for the key registration transaction\n * @example Basic example\n * ```typescript\n * const result = await algorand.send.offlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * })\n * ```\n * @example Advanced example\n * ```typescript\n * const result = await algorand.send.offlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // Use this with caution, it's generally better to use algorand.account.rekeyAccount\n * rekeyTo: 'REKEYTOADDRESS',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * })\n * ```\n * @returns The result of the offline key registration transaction and the transaction that was sent\n */\n offlineKeyRegistration = this._send((c) => c.addOfflineKeyRegistration, {\n preLog: (params, transaction) => `Registering offline key for ${params.sender} via transaction ${transaction.txId()}`,\n })\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"algorand-client-transaction-sender.mjs","names":[],"sources":["../src/algorand-client-transaction-sender.ts"],"sourcesContent":["import { ABIMethod } from '@algorandfoundation/algokit-abi'\nimport { ReadableAddress, getAddress, getApplicationAddress } from '@algorandfoundation/algokit-common'\nimport { Transaction } from '@algorandfoundation/algokit-transact'\nimport { Buffer } from 'buffer'\nimport { SendAppCreateTransactionResult, SendAppTransactionResult, SendAppUpdateTransactionResult } from './app'\nimport { AppManager } from './app-manager'\nimport { AssetManager } from './asset-manager'\nimport {\n AppCallMethodCall,\n AppCallParams,\n AppCreateMethodCall,\n AppCreateParams,\n AppDeleteMethodCall,\n AppDeleteParams,\n AppUpdateMethodCall,\n AppUpdateParams,\n AssetCreateParams,\n AssetOptOutParams,\n TransactionComposer,\n TransactionComposerConfig,\n} from './composer'\nimport { Config } from './config'\nimport { SendParams, SendSingleTransactionResult } from './transaction/types'\nimport { asJson, defaultJsonValueReplacer } from './util'\n\nconst getMethodCallForLog = ({ method, args }: { method: ABIMethod; args?: unknown[] }) => {\n return `${method.name}(${(args ?? []).map((a) =>\n typeof a === 'object'\n ? asJson(a, (k, v) => {\n const newV = defaultJsonValueReplacer(k, v)\n return newV instanceof Uint8Array ? Buffer.from(newV).toString('base64') : newV\n })\n : a,\n )})`\n}\n\n/** Orchestrates sending transactions for `AlgorandClient`. */\nexport class AlgorandClientTransactionSender {\n private _newGroup: () => TransactionComposer\n private _assetManager: AssetManager\n private _appManager: AppManager\n\n /**\n * Creates a new `AlgorandClientSender`\n * @param newGroup A lambda that starts a new `TransactionComposer` transaction group\n * @param assetManager An `AssetManager` instance\n * @param appManager An `AppManager` instance\n * @example\n * ```typescript\n * const transactionSender = new AlgorandClientTransactionSender(() => new TransactionComposer(), assetManager, appManager)\n * ```\n */\n constructor(newGroup: (config?: TransactionComposerConfig) => TransactionComposer, assetManager: AssetManager, appManager: AppManager) {\n this._newGroup = newGroup\n this._assetManager = assetManager\n this._appManager = appManager\n }\n\n /**\n * Start a new `TransactionComposer` transaction group\n * @returns A new instance of `TransactionComposer`.\n * @example\n * const composer = AlgorandClient.mainNet().send.newGroup();\n * const result = await composer.addTransaction(payment).send()\n */\n newGroup() {\n return this._newGroup()\n }\n\n private _send<T>(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendSingleTransactionResult> {\n return async (params) => {\n const composer = this._newGroup()\n\n // Ensure `this` is properly populated\n c(composer).apply(composer, [params])\n\n if (log?.preLog) {\n const transaction = (await composer.build()).transactions.at(-1)!.txn\n Config.getLogger(params?.suppressLog).debug(log.preLog(params, transaction))\n }\n\n const rawResult = await composer.send(params)\n const result = {\n // Last item covers when a group is created by an app call with ABI transaction parameters\n transaction: rawResult.transactions.at(-1)!,\n confirmation: rawResult.confirmations.at(-1)!,\n txId: rawResult.txIds.at(-1)!,\n ...rawResult,\n }\n\n if (log?.postLog) {\n Config.getLogger(params?.suppressLog).debug(log.postLog(params, result))\n }\n\n return result\n }\n }\n\n private _sendAppCall<\n T extends\n | AppCreateParams\n | AppUpdateParams\n | AppCallParams\n | AppDeleteParams\n | AppCreateMethodCall\n | AppUpdateMethodCall\n | AppCallMethodCall\n | AppDeleteMethodCall,\n >(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendAppTransactionResult> {\n return async (params) => {\n const result = await this._send(c, log)(params)\n\n return { ...result, return: AppManager.getABIReturn(result.confirmation, 'method' in params ? params.method : undefined) }\n }\n }\n\n private _sendAppUpdateCall<T extends AppCreateParams | AppUpdateParams | AppCreateMethodCall | AppUpdateMethodCall>(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendAppUpdateTransactionResult> {\n return async (params) => {\n const result = await this._sendAppCall(c, log)(params)\n\n const compiledApproval =\n typeof params.approvalProgram === 'string' ? this._appManager.getCompilationResult(params.approvalProgram) : undefined\n const compiledClear =\n typeof params.clearStateProgram === 'string' ? this._appManager.getCompilationResult(params.clearStateProgram) : undefined\n\n return { ...result, compiledApproval, compiledClear }\n }\n }\n\n private _sendAppCreateCall<T extends AppCreateParams | AppCreateMethodCall>(\n c: (c: TransactionComposer) => (params: T) => TransactionComposer,\n log?: {\n preLog?: (params: T, transaction: Transaction) => string\n postLog?: (params: T, result: SendSingleTransactionResult) => string\n },\n ): (params: T & SendParams) => Promise<SendAppCreateTransactionResult> {\n return async (params) => {\n const result = await this._sendAppUpdateCall(c, log)(params)\n\n return {\n ...result,\n appId: BigInt(result.confirmation.appId!),\n appAddress: getApplicationAddress(result.confirmation.appId!),\n }\n }\n }\n\n /**\n * Send a payment transaction to transfer Algo between accounts.\n * @param params The parameters for the payment transaction\n * @example Basic example\n * {@includeCode ./algorand-client.spec.ts#example-send-payment}\n * @example Advanced example\n * ```typescript\n * const result = await algorand.send.payment({\n * amount: (4).algo(),\n * receiver: 'RECEIVERADDRESS',\n * sender: 'SENDERADDRESS',\n * closeRemainderTo: 'CLOSEREMAINDERTOADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // Use this with caution, it's generally better to use algorand.account.rekeyAccount\n * rekeyTo: 'REKEYTOADDRESS',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @see [Full working example](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/algorand-client.spec.ts)\n * @returns The result of the payment transaction and the transaction that was sent\n */\n payment = this._send((c) => c.addPayment, {\n preLog: (params, transaction) =>\n `Sending ${params.amount.microAlgo} µALGO from ${getAddress(params.sender)} to ${getAddress(params.receiver)} via transaction ${transaction.txId()}`,\n })\n /**\n * Create a new Algorand Standard Asset.\n *\n * The account that sends this transaction will automatically be\n * opted in to the asset and will hold all units after creation.\n *\n * @param params The parameters for the asset creation transaction\n *\n * @example Basic example\n * {@includeCode ./algorand-client.spec.ts#example-send-asset-create}\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetCreate({\n * sender: 'CREATORADDRESS',\n * total: 100n,\n * decimals: 2,\n * assetName: 'asset',\n * unitName: 'unit',\n * url: 'url',\n * metadataHash: 'metadataHash',\n * defaultFrozen: false,\n * manager: 'MANAGERADDRESS',\n * reserve: 'RESERVEADDRESS',\n * freeze: 'FREEZEADDRESS',\n * clawback: 'CLAWBACKADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @see [Full working example](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/algorand-client.spec.ts)\n * @returns The result of the asset create transaction and the transaction that was sent\n */\n assetCreate = async (params: AssetCreateParams & SendParams) => {\n const result = await this._send((c) => c.addAssetCreate, {\n postLog: (params, result) =>\n `Created asset${params.assetName ? ` ${params.assetName}` : ''}${params.unitName ? ` (${params.unitName})` : ''} with ${params.total} units and ${params.decimals ?? 0} decimals created by ${getAddress(params.sender)} with ID ${result.confirmation.assetId} via transaction ${result.txIds.at(-1)}`,\n })(params)\n return { ...result, assetId: BigInt(result.confirmation.assetId ?? 0) }\n }\n /**\n * Configure an existing Algorand Standard Asset.\n *\n * **Note:** The manager, reserve, freeze, and clawback addresses\n * are immutably empty if they are not set. If manager is not set then\n * all fields are immutable from that point forward.\n *\n * @param params The parameters for the asset config transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetConfig({ sender: \"MANAGERADDRESS\", assetId: 123456n, manager: \"MANAGERADDRESS\" })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetConfig({\n * sender: 'MANAGERADDRESS',\n * assetId: 123456n,\n * manager: 'MANAGERADDRESS',\n * reserve: 'RESERVEADDRESS',\n * freeze: 'FREEZEADDRESS',\n * clawback: 'CLAWBACKADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset config transaction and the transaction that was sent\n */\n assetConfig = this._send((c) => c.addAssetConfig, {\n preLog: (params, transaction) => `Configuring asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Freeze or unfreeze an Algorand Standard Asset for an account.\n *\n * @param params The parameters for the asset freeze transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetFreeze({ sender: \"MANAGERADDRESS\", assetId: 123456n, account: \"ACCOUNTADDRESS\", frozen: true })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetFreeze({\n * sender: 'MANAGERADDRESS',\n * assetId: 123456n,\n * account: 'ACCOUNTADDRESS',\n * frozen: true,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset freeze transaction and the transaction that was sent\n */\n assetFreeze = this._send((c) => c.addAssetFreeze, {\n preLog: (params, transaction) => `Freezing asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Destroys an Algorand Standard Asset.\n *\n * Created assets can be destroyed only by the asset manager account.\n * All of the assets must be owned by the creator of the asset before\n * the asset can be deleted.\n *\n * @param params The parameters for the asset destroy transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetDestroy({ sender: \"MANAGERADDRESS\", assetId: 123456n })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetDestroy({\n * sender: 'MANAGERADDRESS',\n * assetId: 123456n,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset destroy transaction and the transaction that was sent\n */\n assetDestroy = this._send((c) => c.addAssetDestroy, {\n preLog: (params, transaction) => `Destroying asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Transfer an Algorand Standard Asset.\n *\n * @param params The parameters for the asset transfer transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetTransfer({ sender: \"HOLDERADDRESS\", assetId: 123456n, amount: 1n, receiver: \"RECEIVERADDRESS\" })\n * ```\n * @example Advanced example (with clawback)\n * ```typescript\n * await algorand.send.assetTransfer({\n * sender: 'CLAWBACKADDRESS',\n * assetId: 123456n,\n * amount: 1n,\n * receiver: 'RECEIVERADDRESS',\n * clawbackTarget: 'HOLDERADDRESS',\n * // This field needs to be used with caution\n * closeAssetTo: 'ADDRESSTOCLOSETO'\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset transfer transaction and the transaction that was sent\n */\n assetTransfer = this._send((c) => c.addAssetTransfer, {\n preLog: (params, transaction) =>\n `Transferring ${params.amount} units of asset with ID ${params.assetId} from ${getAddress(params.sender)} to ${getAddress(params.receiver)} via transaction ${transaction.txId()}`,\n })\n /**\n * Opt an account into an Algorand Standard Asset.\n *\n * @param params The parameters for the asset opt-in transaction\n *\n * @example Basic example\n * ```typescript\n * await algorand.send.assetOptIn({ sender: \"SENDERADDRESS\", assetId: 123456n })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetOptIn({\n * sender: 'SENDERADDRESS',\n * assetId: 123456n,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset opt-in transaction and the transaction that was sent\n */\n assetOptIn = this._send((c) => c.addAssetOptIn, {\n preLog: (params, transaction) =>\n `Opting in ${getAddress(params.sender)} to asset with ID ${params.assetId} via transaction ${transaction.txId()}`,\n })\n /**\n * Opt an account out of an Algorand Standard Asset.\n *\n * *Note:* If the account has a balance of the asset,\n * it will not be able to opt-out unless `ensureZeroBalance`\n * is set to `false` (but then the account will lose the assets).\n *\n * @param params The parameters for the asset opt-out transaction\n *\n * @example Basic example (without creator, will be retrieved from algod)\n * ```typescript\n * await algorand.send.assetOptOut({ sender: \"SENDERADDRESS\", assetId: 123456n, ensureZeroBalance: true })\n * ```\n * @example Basic example (with creator)\n * ```typescript\n * await algorand.send.assetOptOut({ sender: \"SENDERADDRESS\", creator: \"CREATORADDRESS\", assetId: 123456n, ensureZeroBalance: true })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.assetOptOut({\n * sender: 'SENDERADDRESS',\n * assetId: 123456n,\n * creator: 'CREATORADDRESS',\n * ensureZeroBalance: true,\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n * })\n * ```\n * @returns The result of the asset opt-out transaction and the transaction that was sent\n */\n assetOptOut = async (\n params: Omit<AssetOptOutParams, 'creator'> & {\n /** Optional asset creator account address; if not specified it will be retrieved from algod */\n creator?: ReadableAddress\n /** Whether or not to check if the account has a zero balance first or not.\n *\n * If this is set to `true` and the account has an asset balance it will throw an error.\n *\n * If this is set to `false` and the account has an asset balance it will lose those assets to the asset creator.\n */\n ensureZeroBalance: boolean\n } & SendParams,\n ) => {\n if (params.ensureZeroBalance) {\n let balance = 0n\n try {\n const accountAssetInfo = await this._assetManager.getAccountInformation(getAddress(params.sender), params.assetId)\n balance = accountAssetInfo.balance\n } catch {\n throw new Error(`Account ${getAddress(params.sender)} is not opted-in to Asset ${params.assetId}; can't opt-out.`)\n }\n if (balance !== 0n) {\n throw new Error(`Account ${getAddress(params.sender)} does not have a zero balance for Asset ${params.assetId}; can't opt-out.`)\n }\n }\n\n params.creator = params.creator ?? (await this._assetManager.getById(params.assetId)).creator\n\n return await this._send((c) => c.addAssetOptOut, {\n preLog: (params, transaction) =>\n `Opting ${getAddress(params.sender)} out of asset with ID ${params.assetId} to creator ${getAddress(params.creator)} via transaction ${transaction.txId()}`,\n })(params as AssetOptOutParams & SendParams)\n }\n /**\n * Create a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app creation transaction\n * @example Basic example\n * ```typescript\n * const result = await algorand.send.appCreate({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE' })\n * const createdAppId = result.appId\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appCreate({\n * sender: 'CREATORADDRESS',\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * schema: {\n * globalInts: 1,\n * globalByteSlices: 2,\n * localInts: 3,\n * localByteSlices: 4\n * },\n * extraProgramPages: 1,\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app create transaction and the transaction that was sent\n */\n appCreate = this._sendAppCreateCall((c) => c.addAppCreate, {\n postLog: (params, result) =>\n `App created by ${getAddress(params.sender)} with ID ${result.confirmation.appId} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Update a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app update transaction\n * @example Basic example\n * ```typescript\n * await algorand.send.appUpdate({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE' })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appUpdate({\n * sender: 'CREATORADDRESS',\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * onComplete: OnApplicationComplete.UpdateApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app update transaction and the transaction that was sent\n */\n appUpdate = this._sendAppUpdateCall((c) => c.addAppUpdate, {\n postLog: (params, result) =>\n `App ${params.appId} updated ${params.args ? ` with ${params.args.map((a) => Buffer.from(a).toString('base64'))}` : ''} by ${getAddress(params.sender)} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Delete a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app deletion transaction\n * @example Basic example\n * ```typescript\n * await algorand.send.appDelete({ sender: 'CREATORADDRESS' })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appDelete({\n * sender: 'CREATORADDRESS',\n * onComplete: OnApplicationComplete.DeleteApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app delete transaction and the transaction that was sent\n */\n appDelete = this._sendAppCall((c) => c.addAppDelete, {\n postLog: (params, result) =>\n `App ${params.appId} deleted ${params.args ? ` with ${params.args.map((a) => Buffer.from(a).toString('base64'))}` : ''} by ${getAddress(params.sender)} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Call a smart contract.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app call transaction\n * @example Basic example\n * ```typescript\n * await algorand.send.appCall({ sender: 'CREATORADDRESS' })\n * ```\n * @example Advanced example\n * ```typescript\n * await algorand.send.appCall({\n * sender: 'CREATORADDRESS',\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the app call transaction and the transaction that was sent\n */\n appCall = this._sendAppCall((c) => c.addAppCall, {\n postLog: (params, result) =>\n `App ${params.appId} called ${params.args ? ` with ${params.args.map((a) => Buffer.from(a).toString('base64'))}` : ''} by ${getAddress(params.sender)} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Create a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app creation transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * const result = await algorand.send.appCreateMethodCall({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE', method: method, args: [\"arg1_value\"] })\n * const createdAppId = result.appId\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appCreateMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * schema: {\n * globalInts: 1,\n * globalByteSlices: 2,\n * localInts: 3,\n * localByteSlices: 4\n * },\n * extraProgramPages: 1,\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method create transaction and the transaction that was sent\n */\n appCreateMethodCall = this._sendAppCreateCall((c) => c.addAppCreateMethodCall, {\n postLog: (params, result) =>\n `App created by ${getAddress(params.sender)} with ID ${result.confirmation.appId} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Update a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app update transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appUpdateMethodCall({ sender: 'CREATORADDRESS', approvalProgram: 'TEALCODE', clearStateProgram: 'TEALCODE', method: method, args: [\"arg1_value\"] })\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appUpdateMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * approvalProgram: \"TEALCODE\",\n * clearStateProgram: \"TEALCODE\",\n * onComplete: OnApplicationComplete.UpdateApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method update transaction and the transaction that was sent\n */\n appUpdateMethodCall = this._sendAppUpdateCall((c) => c.addAppUpdateMethodCall, {\n postLog: (params, result) =>\n `App ${params.appId} updated with ${getMethodCallForLog(params)} by ${getAddress(params.sender)} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Delete a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app deletion transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appDeleteMethodCall({ sender: 'CREATORADDRESS', method: method, args: [\"arg1_value\"] })\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appDeleteMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * onComplete: OnApplicationComplete.DeleteApplication,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method delete transaction and the transaction that was sent\n */\n appDeleteMethodCall = this._sendAppCall((c) => c.addAppDeleteMethodCall, {\n postLog: (params, result) =>\n `App ${params.appId} deleted with ${getMethodCallForLog(params)} by ${getAddress(params.sender)} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Call a smart contract via an ABI method.\n *\n * Note: you may prefer to use `algorand.client` to get an app client for more advanced functionality.\n *\n * @param params The parameters for the app call transaction\n * @example Basic example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appCallMethodCall({ sender: 'CREATORADDRESS', method: method, args: [\"arg1_value\"] })\n * ```\n * @example Advanced example\n * ```typescript\n * const method = new ABIMethod({\n * name: 'method',\n * args: [{ name: 'arg1', type: 'string' }],\n * returns: { type: 'string' },\n * })\n * await algorand.send.appCallMethodCall({\n * sender: 'CREATORADDRESS',\n * method: method,\n * args: [\"arg1_value\"],\n * onComplete: OnApplicationComplete.OptIn,\n * args: [new Uint8Array(1, 2, 3, 4)]\n * accountReferences: [\"ACCOUNT_1\"]\n * appReferences: [123n, 1234n]\n * assetReferences: [12345n]\n * boxReferences: [\"box1\", {appId: 1234n, name: \"box2\"}]\n * accessReferences: [{ appId: 1234n }]\n * lease: 'lease',\n * note: 'note',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * rejectVersion: 1,\n * // Signer only needed if you want to provide one,\n * // generally you'd register it with AlgorandClient\n * // against the sender and not need to pass it in\n * signer: transactionSigner,\n * maxRoundsToWaitForConfirmation: 5,\n * suppressLog: true,\n *})\n * ```\n * @returns The result of the application ABI method call transaction and the transaction that was sent\n */\n appCallMethodCall = this._sendAppCall((c) => c.addAppCallMethodCall, {\n postLog: (params, result) =>\n `App ${params.appId} called with ${getMethodCallForLog(params)} by ${getAddress(params.sender)} via transaction ${result.txIds.at(-1)}`,\n })\n\n /**\n * Register an online key.\n * @param params The parameters for the key registration transaction\n * @example Basic example\n * ```typescript\n * const result = await algorand.send.onlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * voteKey: Uint8Array.from(Buffer.from(\"voteKeyBase64\", 'base64')),\n * selectionKey: Uint8Array.from(Buffer.from(\"selectionKeyBase64\", 'base64')),\n * stateProofKey: Uint8Array.from(Buffer.from(\"stateProofKeyBase64\", 'base64')),\n * voteFirst: 1n,\n * voteLast: 1000n,\n * voteKeyDilution: 1n,\n * })\n * ```\n * @example Advanced example\n * ```typescript\n * const result = await algorand.send.onlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * voteKey: Uint8Array.from(Buffer.from(\"voteKeyBase64\", 'base64')),\n * selectionKey: Uint8Array.from(Buffer.from(\"selectionKeyBase64\", 'base64')),\n * stateProofKey: Uint8Array.from(Buffer.from(\"stateProofKeyBase64\", 'base64')),\n * voteFirst: 1n,\n * voteLast: 1000n,\n * voteKeyDilution: 1n,\n * lease: 'lease',\n * note: 'note',\n * // Use this with caution, it's generally better to use algorand.account.rekeyAccount\n * rekeyTo: 'REKEYTOADDRESS',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * })\n * ```\n * @returns The result of the online key registration transaction and the transaction that was sent\n */\n onlineKeyRegistration = this._send((c) => c.addOnlineKeyRegistration, {\n preLog: (params, transaction) => `Registering online key for ${getAddress(params.sender)} via transaction ${transaction.txId()}`,\n })\n\n /**\n * Register an offline key.\n * @param params The parameters for the key registration transaction\n * @example Basic example\n * ```typescript\n * const result = await algorand.send.offlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * })\n * ```\n * @example Advanced example\n * ```typescript\n * const result = await algorand.send.offlineKeyRegistration({\n * sender: 'SENDERADDRESS',\n * lease: 'lease',\n * note: 'note',\n * // Use this with caution, it's generally better to use algorand.account.rekeyAccount\n * rekeyTo: 'REKEYTOADDRESS',\n * // You wouldn't normally set this field\n * firstValidRound: 1000n,\n * validityWindow: 10,\n * extraFee: (1000).microAlgo(),\n * staticFee: (1000).microAlgo(),\n * // Max fee doesn't make sense with extraFee AND staticFee\n * // already specified, but here for completeness\n * maxFee: (3000).microAlgo(),\n * })\n * ```\n * @returns The result of the offline key registration transaction and the transaction that was sent\n */\n offlineKeyRegistration = this._send((c) => c.addOfflineKeyRegistration, {\n preLog: (params, transaction) => `Registering offline key for ${getAddress(params.sender)} via transaction ${transaction.txId()}`,\n })\n}\n"],"mappings":"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"}
|
package/app-client.d.ts
CHANGED
|
@@ -458,9 +458,9 @@ declare class AppClient {
|
|
|
458
458
|
signer: AddressWithTransactionSigner | TransactionSigner | undefined;
|
|
459
459
|
method: ABIMethod;
|
|
460
460
|
onComplete: OnApplicationComplete.UpdateApplication;
|
|
461
|
-
args: (Transaction |
|
|
462
|
-
sender: SendingAddress;
|
|
461
|
+
args: (Transaction | Promise<Transaction> | ABIValue | TransactionWithSigner | AppMethodCall<{
|
|
463
462
|
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
463
|
+
sender: SendingAddress;
|
|
464
464
|
rekeyTo?: ReadableAddress | undefined;
|
|
465
465
|
note?: (Uint8Array | string) | undefined;
|
|
466
466
|
lease?: (Uint8Array | string) | undefined;
|
|
@@ -519,9 +519,9 @@ declare class AppClient {
|
|
|
519
519
|
* @returns The parameters which can be used to create an opt-in ABI method call
|
|
520
520
|
*/
|
|
521
521
|
optIn: (params: AppClientMethodCallParams) => Promise<{
|
|
522
|
+
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
522
523
|
appId: bigint;
|
|
523
524
|
sender: SendingAddress;
|
|
524
|
-
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
525
525
|
rekeyTo?: ReadableAddress | undefined;
|
|
526
526
|
note?: (Uint8Array | string) | undefined;
|
|
527
527
|
lease?: (Uint8Array | string) | undefined;
|
|
@@ -547,9 +547,9 @@ declare class AppClient {
|
|
|
547
547
|
* @returns The parameters which can be used to create a delete ABI method call
|
|
548
548
|
*/
|
|
549
549
|
delete: (params: AppClientMethodCallParams) => Promise<{
|
|
550
|
+
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
550
551
|
appId: bigint;
|
|
551
552
|
sender: SendingAddress;
|
|
552
|
-
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
553
553
|
rekeyTo?: ReadableAddress | undefined;
|
|
554
554
|
note?: (Uint8Array | string) | undefined;
|
|
555
555
|
lease?: (Uint8Array | string) | undefined;
|
|
@@ -574,9 +574,9 @@ declare class AppClient {
|
|
|
574
574
|
* @returns The parameters which can be used to create a close out ABI method call
|
|
575
575
|
*/
|
|
576
576
|
closeOut: (params: AppClientMethodCallParams) => Promise<{
|
|
577
|
+
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
577
578
|
appId: bigint;
|
|
578
579
|
sender: SendingAddress;
|
|
579
|
-
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
580
580
|
rekeyTo?: ReadableAddress | undefined;
|
|
581
581
|
note?: (Uint8Array | string) | undefined;
|
|
582
582
|
lease?: (Uint8Array | string) | undefined;
|
|
@@ -601,9 +601,9 @@ declare class AppClient {
|
|
|
601
601
|
* @returns The parameters which can be used to create an ABI method call
|
|
602
602
|
*/
|
|
603
603
|
call: (params: AppClientMethodCallParams & CallOnComplete) => Promise<{
|
|
604
|
+
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
604
605
|
appId: bigint;
|
|
605
606
|
sender: SendingAddress;
|
|
606
|
-
signer?: (TransactionSigner | AddressWithTransactionSigner) | undefined;
|
|
607
607
|
rekeyTo?: ReadableAddress | undefined;
|
|
608
608
|
note?: (Uint8Array | string) | undefined;
|
|
609
609
|
lease?: (Uint8Array | string) | undefined;
|
|
@@ -709,8 +709,8 @@ declare class AppClient {
|
|
|
709
709
|
update: (params: AppClientMethodCallParams & AppClientCompilationParams & SendParams) => Promise<{
|
|
710
710
|
compiledApproval?: CompiledTeal | undefined;
|
|
711
711
|
compiledClear?: CompiledTeal | undefined;
|
|
712
|
-
transactions: Transaction[];
|
|
713
712
|
confirmations: PendingTransactionResponse[];
|
|
713
|
+
transactions: Transaction[];
|
|
714
714
|
groupId: string | undefined;
|
|
715
715
|
txIds: string[];
|
|
716
716
|
returns?: ABIReturn[] | undefined;
|
package/app-deployer.js
CHANGED
|
@@ -74,9 +74,9 @@ var AppDeployer = class {
|
|
|
74
74
|
data: metadata,
|
|
75
75
|
format: "j"
|
|
76
76
|
});
|
|
77
|
-
if (existingDeployments && existingDeployments.creator.toString() !== createParams.sender.toString()) throw new Error(`Received invalid existingDeployments value for creator ${existingDeployments.creator} when attempting to deploy for creator ${createParams.sender}`);
|
|
77
|
+
if (existingDeployments && existingDeployments.creator.toString() !== createParams.sender.toString()) throw new Error(`Received invalid existingDeployments value for creator ${existingDeployments.creator} when attempting to deploy for creator ${require_address.getAddress(createParams.sender)}`);
|
|
78
78
|
if (!existingDeployments && !this._indexer) throw new Error(`Didn't receive an indexer client when this AppManager was created, but also didn't receive an existingDeployments cache - one of them must be provided`);
|
|
79
|
-
require_config.Config.getLogger(sendParams?.suppressLog).info(`Idempotently deploying app "${metadata.name}" from creator ${createParams.sender} using ${createParams.approvalProgram.length} bytes of ${typeof createParams.approvalProgram === "string" ? "teal code" : "AVM bytecode"} and ${createParams.clearStateProgram.length} bytes of ${typeof createParams.approvalProgram === "string" ? "teal code" : "AVM bytecode"}`);
|
|
79
|
+
require_config.Config.getLogger(sendParams?.suppressLog).info(`Idempotently deploying app "${metadata.name}" from creator ${require_address.getAddress(createParams.sender)} using ${createParams.approvalProgram.length} bytes of ${typeof createParams.approvalProgram === "string" ? "teal code" : "AVM bytecode"} and ${createParams.clearStateProgram.length} bytes of ${typeof createParams.approvalProgram === "string" ? "teal code" : "AVM bytecode"}`);
|
|
80
80
|
const compiledApproval = typeof createParams.approvalProgram === "string" ? await this._appManager.compileTealTemplate(createParams.approvalProgram, deployTimeParams, metadata) : void 0;
|
|
81
81
|
const approvalProgram = compiledApproval ? compiledApproval.compiledBase64ToBytes : createParams.approvalProgram;
|
|
82
82
|
const compiledClear = typeof createParams.clearStateProgram === "string" ? await this._appManager.compileTealTemplate(createParams.clearStateProgram, deployTimeParams) : void 0;
|
|
@@ -112,7 +112,7 @@ var AppDeployer = class {
|
|
|
112
112
|
};
|
|
113
113
|
};
|
|
114
114
|
const updateApp = async (existingApp) => {
|
|
115
|
-
require_config.Config.getLogger(sendParams?.suppressLog).info(`Updating existing ${metadata.name} app for ${createParams.sender} to version ${metadata.version}.`);
|
|
115
|
+
require_config.Config.getLogger(sendParams?.suppressLog).info(`Updating existing ${metadata.name} app for ${require_address.getAddress(createParams.sender)} to version ${metadata.version}.`);
|
|
116
116
|
const result = await ("method" in updateParams ? this._transactionSender.appUpdateMethodCall({
|
|
117
117
|
appId: existingApp.appId,
|
|
118
118
|
approvalProgram,
|
|
@@ -145,8 +145,8 @@ var AppDeployer = class {
|
|
|
145
145
|
};
|
|
146
146
|
};
|
|
147
147
|
const replaceApp = async (existingApp) => {
|
|
148
|
-
require_config.Config.getLogger(sendParams?.suppressLog).info(`Deploying a new ${metadata.name} app for ${createParams.sender}; deploying app with version ${metadata.version}.`);
|
|
149
|
-
require_config.Config.getLogger(sendParams?.suppressLog).warn(`Deleting existing ${metadata.name} app with id ${existingApp.appId} from ${deleteParams.sender} account.`);
|
|
148
|
+
require_config.Config.getLogger(sendParams?.suppressLog).info(`Deploying a new ${metadata.name} app for ${require_address.getAddress(createParams.sender)}; deploying app with version ${metadata.version}.`);
|
|
149
|
+
require_config.Config.getLogger(sendParams?.suppressLog).warn(`Deleting existing ${metadata.name} app with id ${existingApp.appId} from ${require_address.getAddress(deleteParams.sender)} account.`);
|
|
150
150
|
const composer = this._transactionSender.newGroup();
|
|
151
151
|
if ("method" in createParams) composer.addAppCreateMethodCall({
|
|
152
152
|
...createParams,
|
|
@@ -171,7 +171,7 @@ var AppDeployer = class {
|
|
|
171
171
|
const confirmation = result.confirmations.at(createIndex - 1);
|
|
172
172
|
const transaction = result.transactions.at(createIndex - 1);
|
|
173
173
|
const deleteTransaction = result.transactions.at(-1);
|
|
174
|
-
require_config.Config.getLogger(sendParams?.suppressLog).warn(`Sent transactions ${transaction.txId()} to create app with id ${confirmation.appId} and ${deleteTransaction.txId()} to delete app with id ${existingApp.appId} from ${createParams.sender} account.`);
|
|
174
|
+
require_config.Config.getLogger(sendParams?.suppressLog).warn(`Sent transactions ${transaction.txId()} to create app with id ${confirmation.appId} and ${deleteTransaction.txId()} to delete app with id ${existingApp.appId} from ${require_address.getAddress(createParams.sender)} account.`);
|
|
175
175
|
const appMetadata = {
|
|
176
176
|
appId: confirmation.appId,
|
|
177
177
|
appAddress: require_address.getApplicationAddress(confirmation.appId),
|
|
@@ -200,10 +200,10 @@ var AppDeployer = class {
|
|
|
200
200
|
};
|
|
201
201
|
const existingApp = (existingDeployments ?? await this.getCreatorAppsByName(createParams.sender, ignoreCache)).apps[metadata.name];
|
|
202
202
|
if (!existingApp || existingApp.deleted) {
|
|
203
|
-
require_config.Config.getLogger(sendParams?.suppressLog).info(`App ${metadata.name} not found in apps created by ${createParams.sender}; deploying app with version ${metadata.version}.`);
|
|
203
|
+
require_config.Config.getLogger(sendParams?.suppressLog).info(`App ${metadata.name} not found in apps created by ${require_address.getAddress(createParams.sender)}; deploying app with version ${metadata.version}.`);
|
|
204
204
|
return await createApp();
|
|
205
205
|
}
|
|
206
|
-
require_config.Config.getLogger(sendParams?.suppressLog).info(`Existing app ${metadata.name} found by creator ${createParams.sender}, with app id ${existingApp.appId} and version ${existingApp.version}.`);
|
|
206
|
+
require_config.Config.getLogger(sendParams?.suppressLog).info(`Existing app ${metadata.name} found by creator ${require_address.getAddress(createParams.sender)}, with app id ${existingApp.appId} and version ${existingApp.version}.`);
|
|
207
207
|
const existingAppRecord = await this._appManager.getById(existingApp.appId);
|
|
208
208
|
const existingApproval = Buffer.from(existingAppRecord.approvalProgram).toString("base64");
|
|
209
209
|
const existingClear = Buffer.from(existingAppRecord.clearStateProgram).toString("base64");
|
|
@@ -238,7 +238,7 @@ var AppDeployer = class {
|
|
|
238
238
|
return await replaceApp(existingApp);
|
|
239
239
|
}
|
|
240
240
|
if (isUpdate) {
|
|
241
|
-
require_config.Config.getLogger(sendParams?.suppressLog).info(`Detected a TEAL update in app ${existingApp.appId} for creator ${createParams.sender}`);
|
|
241
|
+
require_config.Config.getLogger(sendParams?.suppressLog).info(`Detected a TEAL update in app ${existingApp.appId} for creator ${require_address.getAddress(createParams.sender)}`);
|
|
242
242
|
if (onUpdate === void 0 || onUpdate === "fail" || onUpdate === require_app.OnUpdate.Fail) throw new Error("Update detected and onUpdate=Fail, stopping deployment. Try a different onUpdate value to not fail.");
|
|
243
243
|
if (onUpdate === "append" || onUpdate === require_app.OnUpdate.AppendApp) {
|
|
244
244
|
require_config.Config.getLogger(sendParams?.suppressLog).info("onUpdate=AppendApp, will attempt to create a new app");
|
package/app-deployer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-deployer.js","names":["TransactionComposer","APP_DEPLOY_NOTE_DAPP","getApplicationAddress","calculateExtraProgramPages","OnSchemaBreak","OnUpdate","getAddress","Address","lookupAccountCreatedApplicationByAddress","searchTransactions","TransactionType"],"sources":["../src/app-deployer.ts"],"sourcesContent":["import { ABIReturn } from '@algorandfoundation/algokit-abi'\nimport { Address, Expand, getAddress, getApplicationAddress, ReadableAddress } from '@algorandfoundation/algokit-common'\nimport { IndexerClient } from '@algorandfoundation/algokit-indexer-client'\nimport { TransactionType } from '@algorandfoundation/algokit-transact'\nimport { AlgorandClientTransactionSender } from './algorand-client-transaction-sender'\nimport {\n APP_DEPLOY_NOTE_DAPP,\n OnSchemaBreak,\n OnUpdate,\n type AppDeployMetadata,\n type SendAppCreateTransactionResult,\n type SendAppUpdateTransactionResult,\n type TealTemplateParams,\n} from './app'\nimport { AppManager } from './app-manager'\nimport {\n AppCreateMethodCall,\n AppCreateParams,\n AppDeleteMethodCall,\n AppDeleteParams,\n AppUpdateMethodCall,\n AppUpdateParams,\n TransactionComposer,\n} from './composer'\nimport { Config } from './config'\nimport { lookupAccountCreatedApplicationByAddress, searchTransactions } from './indexer-client'\nimport { ConfirmedTransactionResult, SendParams } from './transaction/types'\nimport { calculateExtraProgramPages } from './util'\n\n/** Params to specify an update transaction for an app deployment */\nexport type DeployAppUpdateParams = Expand<Omit<AppUpdateParams, 'appId' | 'approvalProgram' | 'clearStateProgram'>>\n/** Params to specify an update method call for an app deployment */\nexport type DeployAppUpdateMethodCall = Expand<Omit<AppUpdateMethodCall, 'appId' | 'approvalProgram' | 'clearStateProgram'>>\n/** Params to specify a transaction for an app deployment */\nexport type DeployAppDeleteParams = Expand<Omit<AppDeleteParams, 'appId'>>\n/** Params to specify a delete method call for an app deployment */\nexport type DeployAppDeleteMethodCall = Expand<Omit<AppDeleteMethodCall, 'appId'>>\n\n/** The parameters to idempotently deploy an app */\nexport type AppDeployParams = Expand<\n SendParams & {\n /** The deployment metadata */\n metadata: AppDeployMetadata\n /** Any deploy-time parameters to replace in the TEAL code before compiling it (used if teal code is passed in as a string) */\n deployTimeParams?: TealTemplateParams\n /** What action to perform if a schema break (storage schema or extra pages change) is detected:\n *\n * * `fail` - Fail the deployment (throw an error, **default**)\n * * `replace` - Delete the old app and create a new one\n * * `append` - Deploy a new app and leave the old one as is\n */\n onSchemaBreak?: 'replace' | 'fail' | 'append' | OnSchemaBreak\n /** What action to perform if a TEAL code update is detected:\n *\n * * `fail` - Fail the deployment (throw an error, **default**)\n * * `update` - Update the app with the new TEAL code\n * * `replace` - Delete the old app and create a new one\n * * `append` - Deploy a new app and leave the old one as is\n */\n onUpdate?: 'update' | 'replace' | 'fail' | 'append' | OnUpdate\n /** Create transaction parameters to use if a create needs to be issued as part of deployment */\n createParams: AppCreateParams | AppCreateMethodCall\n /** Update transaction parameters to use if an update needs to be issued as part of deployment */\n updateParams: DeployAppUpdateParams | DeployAppUpdateMethodCall\n /** Delete transaction parameters to use if a delete needs to be issued as part of deployment */\n deleteParams: DeployAppDeleteParams | DeployAppDeleteMethodCall\n /** Optional cached value of the existing apps for the given creator; use this to avoid an indexer lookup */\n existingDeployments?: AppLookup\n /** Whether or not to ignore the app metadata cache and force a lookup, default: use the cache **/\n ignoreCache?: boolean\n }\n>\n\n/** The metadata that can be collected about a deployed app */\nexport interface AppMetadata extends AppDeployMetadata {\n /** The id of the app */\n appId: bigint\n /** The Algorand address of the account associated with the app */\n appAddress: Address\n /** The round the app was created */\n createdRound: bigint\n /** The last round that the app was updated */\n updatedRound: bigint\n /** The metadata when the app was created */\n createdMetadata: AppDeployMetadata\n /** Whether or not the app is deleted */\n deleted: boolean\n}\n\n/** A lookup of name -> Algorand app for a creator */\nexport interface AppLookup {\n /** The address of the creator associated with this lookup */\n creator: Readonly<Address>\n /** A hash map of app name to app metadata */\n apps: {\n [name: string]: AppMetadata\n }\n}\n\nexport type AppDeployResult =\n | Expand<{ operationPerformed: 'create' } & Omit<AppMetadata, 'appId' | 'appAddress'> & SendAppCreateTransactionResult>\n | Expand<{ operationPerformed: 'update' } & AppMetadata & SendAppUpdateTransactionResult>\n | Expand<\n { operationPerformed: 'replace' } & Omit<AppMetadata, 'appId' | 'appAddress'> &\n SendAppCreateTransactionResult & {\n deleteReturn?: ABIReturn\n deleteResult: ConfirmedTransactionResult\n }\n >\n | Expand<{ operationPerformed: 'nothing' } & AppMetadata>\n\n/** Allows management of deployment and deployment metadata of applications. */\nexport class AppDeployer {\n private _appManager: AppManager\n private _transactionSender: AlgorandClientTransactionSender\n private _indexer?: IndexerClient\n private _appLookups = new Map<string, AppLookup>()\n\n /**\n * Creates an `AppManager`\n * @param appManager An `AppManager` instance\n * @param transactionSender An `AlgorandClientTransactionSender` instance\n * @param indexer An optional indexer instance; supply if you want to indexer to look up app metadata\n * @example\n * ```ts\n * const deployer = new AppDeployer(appManager, transactionSender, indexer)\n * ```\n */\n constructor(appManager: AppManager, transactionSender: AlgorandClientTransactionSender, indexer?: IndexerClient) {\n this._appManager = appManager\n this._transactionSender = transactionSender\n this._indexer = indexer\n }\n\n /**\n * Idempotently deploy (create if not exists, update if changed) an app against the given name for the given creator account, including deploy-time TEAL template placeholder substitutions (if specified).\n *\n * To understand the architecture decisions behind this functionality please see https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md\n *\n * **Note:** When using the return from this function be sure to check `operationPerformed` to get access to various return properties like `transaction`, `confirmation` and `deleteResult`.\n *\n * **Note:** if there is a breaking state schema change to an existing app (and `onSchemaBreak` is set to `'replace'`) the existing app will be deleted and re-created.\n *\n * **Note:** if there is an update (different TEAL code) to an existing app (and `onUpdate` is set to `'replace'`) the existing app will be deleted and re-created.\n * @param deployment The arguments to control the app deployment\n * @returns The result of the deployment\n * @example\n * ```ts\n * const deployResult = await deployer.deploy({\n * createParams: {\n * sender: 'SENDER_ADDRESS',\n * approvalProgram: 'APPROVAL PROGRAM',\n * clearStateProgram: 'CLEAR PROGRAM',\n * schema: {\n * globalByteSlices: 0,\n * globalInts: 0,\n * localByteSlices: 0,\n * localInts: 0\n * }\n * },\n * updateParams: {\n * sender: 'SENDER_ADDRESS'\n * },\n * deleteParams: {\n * sender: 'SENDER_ADDRESS'\n * },\n * metadata: { name: 'my_app', version: '2.0', updatable: false, deletable: false },\n * onSchemaBreak: 'append',\n * onUpdate: 'append'\n * })\n * ```\n */\n async deploy(deployment: AppDeployParams): Promise<AppDeployResult> {\n const {\n metadata,\n deployTimeParams,\n onSchemaBreak,\n onUpdate,\n createParams,\n updateParams,\n deleteParams,\n existingDeployments,\n ignoreCache,\n ...sendParams\n } = deployment\n\n // Set creation note\n\n createParams.note = updateParams.note = TransactionComposer.arc2Note({\n dAppName: APP_DEPLOY_NOTE_DAPP,\n data: metadata,\n format: 'j',\n })\n\n // Check for required fields\n\n if (existingDeployments && existingDeployments.creator.toString() !== createParams.sender.toString()) {\n throw new Error(\n `Received invalid existingDeployments value for creator ${existingDeployments.creator} when attempting to deploy for creator ${createParams.sender}`,\n )\n }\n if (!existingDeployments && !this._indexer) {\n throw new Error(\n `Didn't receive an indexer client when this AppManager was created, but also didn't receive an existingDeployments cache - one of them must be provided`,\n )\n }\n\n Config.getLogger(sendParams?.suppressLog).info(\n `Idempotently deploying app \"${metadata.name}\" from creator ${createParams.sender} using ${createParams.approvalProgram.length} bytes of ${typeof createParams.approvalProgram === 'string' ? 'teal code' : 'AVM bytecode'} and ${createParams.clearStateProgram.length} bytes of ${typeof createParams.approvalProgram === 'string' ? 'teal code' : 'AVM bytecode'}`,\n )\n\n // Compile code if required\n\n const compiledApproval =\n typeof createParams.approvalProgram === 'string'\n ? await this._appManager.compileTealTemplate(createParams.approvalProgram, deployTimeParams, metadata)\n : undefined\n const approvalProgram = compiledApproval ? compiledApproval.compiledBase64ToBytes : createParams.approvalProgram\n\n const compiledClear =\n typeof createParams.clearStateProgram === 'string'\n ? await this._appManager.compileTealTemplate(createParams.clearStateProgram, deployTimeParams)\n : undefined\n const clearStateProgram = compiledClear ? compiledClear.compiledBase64ToBytes : createParams.clearStateProgram\n\n // Define routines for create, update, and replace\n\n const createApp = async () => {\n const result = await ('method' in createParams\n ? this._transactionSender.appCreateMethodCall({ ...createParams, approvalProgram, clearStateProgram, ...sendParams })\n : this._transactionSender.appCreate({ ...createParams, approvalProgram, clearStateProgram, ...sendParams }))\n const appMetadata: AppMetadata = {\n appId: result.appId,\n appAddress: result.appAddress,\n ...metadata,\n createdMetadata: metadata,\n createdRound: BigInt(result.confirmation.confirmedRound!),\n updatedRound: BigInt(result.confirmation.confirmedRound!),\n deleted: false,\n }\n this.updateAppLookup(createParams.sender, appMetadata)\n return {\n operationPerformed: 'create',\n compiledApproval,\n compiledClear,\n ...result,\n ...appMetadata,\n } satisfies SendAppCreateTransactionResult & AppMetadata & { operationPerformed: 'create' }\n }\n const updateApp = async (existingApp: AppMetadata) => {\n Config.getLogger(sendParams?.suppressLog).info(\n `Updating existing ${metadata.name} app for ${createParams.sender} to version ${metadata.version}.`,\n )\n const result = await ('method' in updateParams\n ? this._transactionSender.appUpdateMethodCall({\n appId: existingApp.appId,\n approvalProgram,\n clearStateProgram,\n ...updateParams,\n ...sendParams,\n })\n : this._transactionSender.appUpdate({\n appId: existingApp.appId,\n approvalProgram,\n clearStateProgram,\n ...updateParams,\n ...sendParams,\n }))\n const appMetadata: AppMetadata = {\n appId: existingApp.appId,\n appAddress: existingApp.appAddress,\n createdMetadata: existingApp.createdMetadata,\n createdRound: existingApp.createdRound,\n updatedRound: BigInt(result.confirmation.confirmedRound!),\n ...metadata,\n deleted: false,\n }\n this.updateAppLookup(createParams.sender, appMetadata)\n return {\n operationPerformed: 'update',\n compiledApproval,\n compiledClear,\n ...result,\n ...appMetadata,\n } satisfies SendAppUpdateTransactionResult & AppMetadata & { operationPerformed: 'update' }\n }\n const replaceApp = async (existingApp: AppMetadata) => {\n Config.getLogger(sendParams?.suppressLog).info(\n `Deploying a new ${metadata.name} app for ${createParams.sender}; deploying app with version ${metadata.version}.`,\n )\n\n Config.getLogger(sendParams?.suppressLog).warn(\n `Deleting existing ${metadata.name} app with id ${existingApp.appId} from ${deleteParams.sender} account.`,\n )\n\n const composer = this._transactionSender.newGroup()\n if ('method' in createParams) {\n composer.addAppCreateMethodCall({ ...createParams, approvalProgram, clearStateProgram })\n } else {\n composer.addAppCreate({ ...createParams, approvalProgram, clearStateProgram })\n }\n const createIndex = await composer.count()\n if ('method' in deleteParams) {\n composer.addAppDeleteMethodCall({ appId: existingApp.appId, ...deleteParams })\n } else {\n composer.addAppDelete({ appId: existingApp.appId, ...deleteParams })\n }\n const result = await composer.send({ ...sendParams })\n const confirmation = result.confirmations.at(createIndex - 1)!\n const transaction = result.transactions.at(createIndex - 1)!\n const deleteTransaction = result.transactions.at(-1)!\n\n Config.getLogger(sendParams?.suppressLog).warn(\n `Sent transactions ${transaction.txId()} to create app with id ${confirmation.appId} and ${deleteTransaction.txId()} to delete app with id ${\n existingApp.appId\n } from ${createParams.sender} account.`,\n )\n\n const appMetadata: AppMetadata = {\n appId: confirmation.appId!,\n appAddress: getApplicationAddress(confirmation.appId!),\n ...metadata,\n createdMetadata: metadata,\n createdRound: BigInt(confirmation.confirmedRound!),\n updatedRound: BigInt(confirmation.confirmedRound!),\n deleted: false,\n }\n this.updateAppLookup(createParams.sender, appMetadata)\n\n return {\n operationPerformed: 'replace',\n ...result,\n compiledApproval,\n compiledClear,\n transaction,\n confirmation,\n return: 'method' in createParams ? result.returns?.[0] : undefined,\n deleteReturn: 'method' in deleteParams ? result.returns?.at(-1) : undefined,\n ...appMetadata,\n deleteResult: { transaction: deleteTransaction, confirmation: result.confirmations.at(-1)! },\n } satisfies { operationPerformed: 'replace' } & AppMetadata &\n SendAppCreateTransactionResult & {\n deleteReturn?: ABIReturn\n deleteResult: ConfirmedTransactionResult\n }\n }\n\n // Lookup existing app metadata\n\n const apps = existingDeployments ?? (await this.getCreatorAppsByName(createParams.sender, ignoreCache))\n\n const existingApp = apps.apps[metadata.name]\n if (!existingApp || existingApp.deleted) {\n Config.getLogger(sendParams?.suppressLog).info(\n `App ${metadata.name} not found in apps created by ${createParams.sender}; deploying app with version ${metadata.version}.`,\n )\n\n return await createApp()\n }\n\n Config.getLogger(sendParams?.suppressLog).info(\n `Existing app ${metadata.name} found by creator ${createParams.sender}, with app id ${existingApp.appId} and version ${existingApp.version}.`,\n )\n\n const existingAppRecord = await this._appManager.getById(existingApp.appId)\n const existingApproval = Buffer.from(existingAppRecord.approvalProgram).toString('base64')\n const existingClear = Buffer.from(existingAppRecord.clearStateProgram).toString('base64')\n const extraPages = existingAppRecord.extraProgramPages ?? 0\n\n const newApprovalBytes = Buffer.from(approvalProgram)\n const newClearBytes = Buffer.from(clearStateProgram)\n const newApproval = newApprovalBytes.toString('base64')\n const newClear = newClearBytes.toString('base64')\n const newExtraPages = calculateExtraProgramPages(newApprovalBytes, newClearBytes)\n\n // Check for changes\n\n const isUpdate = newApproval !== existingApproval || newClear !== existingClear\n const isSchemaBreak =\n existingAppRecord.localInts < (createParams.schema?.localInts ?? 0) ||\n existingAppRecord.globalInts < (createParams.schema?.globalInts ?? 0) ||\n existingAppRecord.localByteSlices < (createParams.schema?.localByteSlices ?? 0) ||\n existingAppRecord.globalByteSlices < (createParams.schema?.globalByteSlices ?? 0) ||\n extraPages < newExtraPages\n\n if (isSchemaBreak) {\n Config.getLogger(sendParams?.suppressLog).warn(`Detected a breaking app schema change in app ${existingApp.appId}:`, {\n from: {\n globalInts: existingAppRecord.globalInts,\n globalByteSlices: existingAppRecord.globalByteSlices,\n localInts: existingAppRecord.localInts,\n localByteSlices: existingAppRecord.localByteSlices,\n extraProgramPages: extraPages,\n },\n to: { ...createParams.schema, extraProgramPages: newExtraPages },\n })\n\n if (onSchemaBreak === undefined || onSchemaBreak === 'fail' || onSchemaBreak === OnSchemaBreak.Fail) {\n throw new Error(\n 'Schema break detected and onSchemaBreak=OnSchemaBreak.Fail, stopping deployment. ' +\n 'If you want to try deleting and recreating the app then ' +\n 're-run with onSchemaBreak=OnSchemaBreak.ReplaceApp',\n )\n }\n\n if (onSchemaBreak === 'append' || onSchemaBreak === OnSchemaBreak.AppendApp) {\n Config.getLogger(sendParams?.suppressLog).info('onSchemaBreak=AppendApp, will attempt to create a new app')\n return await createApp()\n }\n\n if (existingApp.deletable) {\n Config.getLogger(sendParams?.suppressLog).info(\n 'App is deletable and onSchemaBreak=ReplaceApp, will attempt to create new app and delete old app',\n )\n } else {\n Config.getLogger(sendParams?.suppressLog).info(\n 'App is not deletable but onSchemaBreak=ReplaceApp, will attempt to delete app, delete will most likely fail',\n )\n }\n\n return await replaceApp(existingApp)\n }\n\n if (isUpdate) {\n Config.getLogger(sendParams?.suppressLog).info(\n `Detected a TEAL update in app ${existingApp.appId} for creator ${createParams.sender}`,\n )\n\n if (onUpdate === undefined || onUpdate === 'fail' || onUpdate === OnUpdate.Fail) {\n throw new Error('Update detected and onUpdate=Fail, stopping deployment. Try a different onUpdate value to not fail.')\n }\n\n if (onUpdate === 'append' || onUpdate === OnUpdate.AppendApp) {\n Config.getLogger(sendParams?.suppressLog).info('onUpdate=AppendApp, will attempt to create a new app')\n return await createApp()\n }\n\n if (onUpdate === 'update' || onUpdate === OnUpdate.UpdateApp) {\n if (existingApp.updatable) {\n Config.getLogger(sendParams?.suppressLog).info(`App is updatable and onUpdate=UpdateApp, updating app...`)\n } else {\n Config.getLogger(sendParams?.suppressLog).warn(\n `App is not updatable but onUpdate=UpdateApp, will attempt to update app, update will most likely fail`,\n )\n }\n\n return await updateApp(existingApp)\n }\n\n if (onUpdate === 'replace' || onUpdate === OnUpdate.ReplaceApp) {\n if (existingApp.deletable) {\n Config.getLogger(sendParams?.suppressLog).warn(\n 'App is deletable and onUpdate=ReplaceApp, creating new app and deleting old app...',\n )\n } else {\n Config.getLogger(sendParams?.suppressLog).warn(\n 'App is not deletable and onUpdate=ReplaceApp, will attempt to create new app and delete old app, delete will most likely fail',\n )\n }\n\n return await replaceApp(existingApp)\n }\n }\n\n Config.getLogger(sendParams?.suppressLog).debug('No detected changes in app, nothing to do.')\n\n return { ...existingApp, operationPerformed: 'nothing' }\n }\n\n private updateAppLookup(sender: ReadableAddress, appMetadata: AppMetadata) {\n const s = getAddress(sender).toString()\n const lookup = this._appLookups.get(s)\n if (!lookup) {\n this._appLookups.set(s, { creator: Address.fromString(s), apps: { [appMetadata.name]: appMetadata } })\n } else {\n lookup.apps[appMetadata.name] = appMetadata\n }\n }\n\n /**\n * Returns a lookup of name => app metadata (id, address, ...metadata) for all apps created by the given account that have\n * an [ARC-2](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md) `AppDeployNote` as the transaction\n * note of the app creation transaction.\n *\n * This function caches the result for the given creator account so that subsequent calls will not require an indexer lookup.\n *\n * If the `AppManager` instance wasn't created with an indexer client, this function will throw an error.\n *\n * @param creator The address of the account that is the creator of the apps you want to search for\n * @param ignoreCache Whether or not to ignore the cache and force a lookup, default: use the cache\n * @returns A name-based lookup of the app metadata\n * @example\n * ```ts\n * const result = await deployer.getCreatorAppsByName(creator)\n */\n async getCreatorAppsByName(creator: ReadableAddress, ignoreCache?: boolean): Promise<AppLookup> {\n const appLookup: Record<string, AppMetadata> = {}\n\n const creatorAddress = getAddress(creator)\n const creatorString = creatorAddress.toString()\n if (!ignoreCache && this._appLookups.has(creatorString)) {\n return this._appLookups.get(creatorString)!\n }\n\n if (!this._indexer) {\n throw new Error(`Didn't receive an indexer client when this AppManager was created, but received a call to getCreatorApps`)\n }\n\n // Extract all apps that account created\n const createdApps = (await lookupAccountCreatedApplicationByAddress(this._indexer, creatorString))\n .map((a) => {\n return { id: a.id, createdAtRound: a.createdAtRound!, deleted: a.deleted }\n })\n .sort((a, b) => Number(a.createdAtRound - b.createdAtRound))\n\n // For each app that account created (in parallel)...\n const apps = await Promise.all(\n createdApps.map(async (createdApp) => {\n // Find any app transactions for that app in the round it was created (should always just be a single creation transaction)\n const appTransactions = await searchTransactions(this._indexer!, {\n minRound: createdApp.createdAtRound,\n txType: TransactionType.AppCall,\n applicationId: createdApp.id,\n address: creatorAddress,\n addressRole: 'sender',\n notePrefix: Buffer.from(APP_DEPLOY_NOTE_DAPP).toString('base64'),\n })\n\n // Triple check the transaction is intact by filtering for the one we want:\n // * application-id is 0 when the app is first created\n // * also verify the sender to prevent a potential security risk\n const appCreationTransaction = appTransactions.transactions.filter(\n (t) => t.applicationTransaction?.applicationId === 0n && t.sender.toString() === creatorAddress.toString(),\n )[0]\n\n const latestAppUpdateTransaction = appTransactions.transactions\n .filter((t) => t.sender.toString() === creatorAddress.toString())\n .sort((a, b) =>\n a.confirmedRound === b.confirmedRound\n ? (b.intraRoundOffset! - a.intraRoundOffset!) / 10\n : Number(b.confirmedRound! - a.confirmedRound!),\n )[0]\n\n if (!appCreationTransaction?.note)\n // No note; ignoring\n return null\n\n return { createdApp, appCreationTransaction, latestAppUpdateTransaction }\n }),\n )\n\n apps\n .filter((a) => a !== null)\n .forEach((a) => {\n const { createdApp, appCreationTransaction, latestAppUpdateTransaction } = a!\n\n const parseNote = (note?: string) => {\n if (!note) {\n // No note; ignoring...\n return\n }\n\n if (!note.startsWith(`${APP_DEPLOY_NOTE_DAPP}:j{`))\n // Clearly not APP_DEPLOY JSON; ignoring...\n return\n\n return JSON.parse(note.substring(APP_DEPLOY_NOTE_DAPP.length + 2)) as AppDeployMetadata\n }\n\n try {\n const creationNote = parseNote(\n appCreationTransaction.note ? Buffer.from(appCreationTransaction.note).toString('utf-8') : undefined,\n )\n const updateNote = parseNote(\n latestAppUpdateTransaction.note ? Buffer.from(latestAppUpdateTransaction.note).toString('utf-8') : undefined,\n )\n if (creationNote?.name) {\n appLookup[creationNote.name] = {\n appId: createdApp.id,\n appAddress: getApplicationAddress(createdApp.id),\n createdMetadata: creationNote,\n createdRound: appCreationTransaction.confirmedRound ?? 0n,\n ...(updateNote ?? creationNote),\n updatedRound: latestAppUpdateTransaction?.confirmedRound ?? 0n,\n deleted: createdApp.deleted ?? false,\n }\n }\n } catch (e) {\n Config.logger.warn(\n `Received error trying to retrieve app with ${createdApp.id} for creator ${creatorAddress}; failing silently`,\n e,\n )\n return\n }\n })\n\n const lookup = {\n creator: creatorAddress,\n apps: appLookup,\n }\n\n this._appLookups.set(creatorString, lookup)\n\n return lookup\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-deployer.js","names":["TransactionComposer","APP_DEPLOY_NOTE_DAPP","getAddress","getApplicationAddress","calculateExtraProgramPages","OnSchemaBreak","OnUpdate","Address","lookupAccountCreatedApplicationByAddress","searchTransactions","TransactionType"],"sources":["../src/app-deployer.ts"],"sourcesContent":["import { ABIReturn } from '@algorandfoundation/algokit-abi'\nimport { Address, Expand, getAddress, getApplicationAddress, ReadableAddress } from '@algorandfoundation/algokit-common'\nimport { IndexerClient } from '@algorandfoundation/algokit-indexer-client'\nimport { TransactionType } from '@algorandfoundation/algokit-transact'\nimport { AlgorandClientTransactionSender } from './algorand-client-transaction-sender'\nimport {\n APP_DEPLOY_NOTE_DAPP,\n OnSchemaBreak,\n OnUpdate,\n type AppDeployMetadata,\n type SendAppCreateTransactionResult,\n type SendAppUpdateTransactionResult,\n type TealTemplateParams,\n} from './app'\nimport { AppManager } from './app-manager'\nimport {\n AppCreateMethodCall,\n AppCreateParams,\n AppDeleteMethodCall,\n AppDeleteParams,\n AppUpdateMethodCall,\n AppUpdateParams,\n TransactionComposer,\n} from './composer'\nimport { Config } from './config'\nimport { lookupAccountCreatedApplicationByAddress, searchTransactions } from './indexer-client'\nimport { ConfirmedTransactionResult, SendParams } from './transaction/types'\nimport { calculateExtraProgramPages } from './util'\n\n/** Params to specify an update transaction for an app deployment */\nexport type DeployAppUpdateParams = Expand<Omit<AppUpdateParams, 'appId' | 'approvalProgram' | 'clearStateProgram'>>\n/** Params to specify an update method call for an app deployment */\nexport type DeployAppUpdateMethodCall = Expand<Omit<AppUpdateMethodCall, 'appId' | 'approvalProgram' | 'clearStateProgram'>>\n/** Params to specify a transaction for an app deployment */\nexport type DeployAppDeleteParams = Expand<Omit<AppDeleteParams, 'appId'>>\n/** Params to specify a delete method call for an app deployment */\nexport type DeployAppDeleteMethodCall = Expand<Omit<AppDeleteMethodCall, 'appId'>>\n\n/** The parameters to idempotently deploy an app */\nexport type AppDeployParams = Expand<\n SendParams & {\n /** The deployment metadata */\n metadata: AppDeployMetadata\n /** Any deploy-time parameters to replace in the TEAL code before compiling it (used if teal code is passed in as a string) */\n deployTimeParams?: TealTemplateParams\n /** What action to perform if a schema break (storage schema or extra pages change) is detected:\n *\n * * `fail` - Fail the deployment (throw an error, **default**)\n * * `replace` - Delete the old app and create a new one\n * * `append` - Deploy a new app and leave the old one as is\n */\n onSchemaBreak?: 'replace' | 'fail' | 'append' | OnSchemaBreak\n /** What action to perform if a TEAL code update is detected:\n *\n * * `fail` - Fail the deployment (throw an error, **default**)\n * * `update` - Update the app with the new TEAL code\n * * `replace` - Delete the old app and create a new one\n * * `append` - Deploy a new app and leave the old one as is\n */\n onUpdate?: 'update' | 'replace' | 'fail' | 'append' | OnUpdate\n /** Create transaction parameters to use if a create needs to be issued as part of deployment */\n createParams: AppCreateParams | AppCreateMethodCall\n /** Update transaction parameters to use if an update needs to be issued as part of deployment */\n updateParams: DeployAppUpdateParams | DeployAppUpdateMethodCall\n /** Delete transaction parameters to use if a delete needs to be issued as part of deployment */\n deleteParams: DeployAppDeleteParams | DeployAppDeleteMethodCall\n /** Optional cached value of the existing apps for the given creator; use this to avoid an indexer lookup */\n existingDeployments?: AppLookup\n /** Whether or not to ignore the app metadata cache and force a lookup, default: use the cache **/\n ignoreCache?: boolean\n }\n>\n\n/** The metadata that can be collected about a deployed app */\nexport interface AppMetadata extends AppDeployMetadata {\n /** The id of the app */\n appId: bigint\n /** The Algorand address of the account associated with the app */\n appAddress: Address\n /** The round the app was created */\n createdRound: bigint\n /** The last round that the app was updated */\n updatedRound: bigint\n /** The metadata when the app was created */\n createdMetadata: AppDeployMetadata\n /** Whether or not the app is deleted */\n deleted: boolean\n}\n\n/** A lookup of name -> Algorand app for a creator */\nexport interface AppLookup {\n /** The address of the creator associated with this lookup */\n creator: Readonly<Address>\n /** A hash map of app name to app metadata */\n apps: {\n [name: string]: AppMetadata\n }\n}\n\nexport type AppDeployResult =\n | Expand<{ operationPerformed: 'create' } & Omit<AppMetadata, 'appId' | 'appAddress'> & SendAppCreateTransactionResult>\n | Expand<{ operationPerformed: 'update' } & AppMetadata & SendAppUpdateTransactionResult>\n | Expand<\n { operationPerformed: 'replace' } & Omit<AppMetadata, 'appId' | 'appAddress'> &\n SendAppCreateTransactionResult & {\n deleteReturn?: ABIReturn\n deleteResult: ConfirmedTransactionResult\n }\n >\n | Expand<{ operationPerformed: 'nothing' } & AppMetadata>\n\n/** Allows management of deployment and deployment metadata of applications. */\nexport class AppDeployer {\n private _appManager: AppManager\n private _transactionSender: AlgorandClientTransactionSender\n private _indexer?: IndexerClient\n private _appLookups = new Map<string, AppLookup>()\n\n /**\n * Creates an `AppManager`\n * @param appManager An `AppManager` instance\n * @param transactionSender An `AlgorandClientTransactionSender` instance\n * @param indexer An optional indexer instance; supply if you want to indexer to look up app metadata\n * @example\n * ```ts\n * const deployer = new AppDeployer(appManager, transactionSender, indexer)\n * ```\n */\n constructor(appManager: AppManager, transactionSender: AlgorandClientTransactionSender, indexer?: IndexerClient) {\n this._appManager = appManager\n this._transactionSender = transactionSender\n this._indexer = indexer\n }\n\n /**\n * Idempotently deploy (create if not exists, update if changed) an app against the given name for the given creator account, including deploy-time TEAL template placeholder substitutions (if specified).\n *\n * To understand the architecture decisions behind this functionality please see https://github.com/algorandfoundation/algokit-cli/blob/main/docs/architecture-decisions/2023-01-12_smart-contract-deployment.md\n *\n * **Note:** When using the return from this function be sure to check `operationPerformed` to get access to various return properties like `transaction`, `confirmation` and `deleteResult`.\n *\n * **Note:** if there is a breaking state schema change to an existing app (and `onSchemaBreak` is set to `'replace'`) the existing app will be deleted and re-created.\n *\n * **Note:** if there is an update (different TEAL code) to an existing app (and `onUpdate` is set to `'replace'`) the existing app will be deleted and re-created.\n * @param deployment The arguments to control the app deployment\n * @returns The result of the deployment\n * @example\n * ```ts\n * const deployResult = await deployer.deploy({\n * createParams: {\n * sender: 'SENDER_ADDRESS',\n * approvalProgram: 'APPROVAL PROGRAM',\n * clearStateProgram: 'CLEAR PROGRAM',\n * schema: {\n * globalByteSlices: 0,\n * globalInts: 0,\n * localByteSlices: 0,\n * localInts: 0\n * }\n * },\n * updateParams: {\n * sender: 'SENDER_ADDRESS'\n * },\n * deleteParams: {\n * sender: 'SENDER_ADDRESS'\n * },\n * metadata: { name: 'my_app', version: '2.0', updatable: false, deletable: false },\n * onSchemaBreak: 'append',\n * onUpdate: 'append'\n * })\n * ```\n */\n async deploy(deployment: AppDeployParams): Promise<AppDeployResult> {\n const {\n metadata,\n deployTimeParams,\n onSchemaBreak,\n onUpdate,\n createParams,\n updateParams,\n deleteParams,\n existingDeployments,\n ignoreCache,\n ...sendParams\n } = deployment\n\n // Set creation note\n\n createParams.note = updateParams.note = TransactionComposer.arc2Note({\n dAppName: APP_DEPLOY_NOTE_DAPP,\n data: metadata,\n format: 'j',\n })\n\n // Check for required fields\n\n if (existingDeployments && existingDeployments.creator.toString() !== createParams.sender.toString()) {\n throw new Error(\n `Received invalid existingDeployments value for creator ${existingDeployments.creator} when attempting to deploy for creator ${getAddress(createParams.sender)}`,\n )\n }\n if (!existingDeployments && !this._indexer) {\n throw new Error(\n `Didn't receive an indexer client when this AppManager was created, but also didn't receive an existingDeployments cache - one of them must be provided`,\n )\n }\n\n Config.getLogger(sendParams?.suppressLog).info(\n `Idempotently deploying app \"${metadata.name}\" from creator ${getAddress(createParams.sender)} using ${createParams.approvalProgram.length} bytes of ${typeof createParams.approvalProgram === 'string' ? 'teal code' : 'AVM bytecode'} and ${createParams.clearStateProgram.length} bytes of ${typeof createParams.approvalProgram === 'string' ? 'teal code' : 'AVM bytecode'}`,\n )\n\n // Compile code if required\n\n const compiledApproval =\n typeof createParams.approvalProgram === 'string'\n ? await this._appManager.compileTealTemplate(createParams.approvalProgram, deployTimeParams, metadata)\n : undefined\n const approvalProgram = compiledApproval ? compiledApproval.compiledBase64ToBytes : createParams.approvalProgram\n\n const compiledClear =\n typeof createParams.clearStateProgram === 'string'\n ? await this._appManager.compileTealTemplate(createParams.clearStateProgram, deployTimeParams)\n : undefined\n const clearStateProgram = compiledClear ? compiledClear.compiledBase64ToBytes : createParams.clearStateProgram\n\n // Define routines for create, update, and replace\n\n const createApp = async () => {\n const result = await ('method' in createParams\n ? this._transactionSender.appCreateMethodCall({ ...createParams, approvalProgram, clearStateProgram, ...sendParams })\n : this._transactionSender.appCreate({ ...createParams, approvalProgram, clearStateProgram, ...sendParams }))\n const appMetadata: AppMetadata = {\n appId: result.appId,\n appAddress: result.appAddress,\n ...metadata,\n createdMetadata: metadata,\n createdRound: BigInt(result.confirmation.confirmedRound!),\n updatedRound: BigInt(result.confirmation.confirmedRound!),\n deleted: false,\n }\n this.updateAppLookup(createParams.sender, appMetadata)\n return {\n operationPerformed: 'create',\n compiledApproval,\n compiledClear,\n ...result,\n ...appMetadata,\n } satisfies SendAppCreateTransactionResult & AppMetadata & { operationPerformed: 'create' }\n }\n const updateApp = async (existingApp: AppMetadata) => {\n Config.getLogger(sendParams?.suppressLog).info(\n `Updating existing ${metadata.name} app for ${getAddress(createParams.sender)} to version ${metadata.version}.`,\n )\n const result = await ('method' in updateParams\n ? this._transactionSender.appUpdateMethodCall({\n appId: existingApp.appId,\n approvalProgram,\n clearStateProgram,\n ...updateParams,\n ...sendParams,\n })\n : this._transactionSender.appUpdate({\n appId: existingApp.appId,\n approvalProgram,\n clearStateProgram,\n ...updateParams,\n ...sendParams,\n }))\n const appMetadata: AppMetadata = {\n appId: existingApp.appId,\n appAddress: existingApp.appAddress,\n createdMetadata: existingApp.createdMetadata,\n createdRound: existingApp.createdRound,\n updatedRound: BigInt(result.confirmation.confirmedRound!),\n ...metadata,\n deleted: false,\n }\n this.updateAppLookup(createParams.sender, appMetadata)\n return {\n operationPerformed: 'update',\n compiledApproval,\n compiledClear,\n ...result,\n ...appMetadata,\n } satisfies SendAppUpdateTransactionResult & AppMetadata & { operationPerformed: 'update' }\n }\n const replaceApp = async (existingApp: AppMetadata) => {\n Config.getLogger(sendParams?.suppressLog).info(\n `Deploying a new ${metadata.name} app for ${getAddress(createParams.sender)}; deploying app with version ${metadata.version}.`,\n )\n\n Config.getLogger(sendParams?.suppressLog).warn(\n `Deleting existing ${metadata.name} app with id ${existingApp.appId} from ${getAddress(deleteParams.sender)} account.`,\n )\n\n const composer = this._transactionSender.newGroup()\n if ('method' in createParams) {\n composer.addAppCreateMethodCall({ ...createParams, approvalProgram, clearStateProgram })\n } else {\n composer.addAppCreate({ ...createParams, approvalProgram, clearStateProgram })\n }\n const createIndex = await composer.count()\n if ('method' in deleteParams) {\n composer.addAppDeleteMethodCall({ appId: existingApp.appId, ...deleteParams })\n } else {\n composer.addAppDelete({ appId: existingApp.appId, ...deleteParams })\n }\n const result = await composer.send({ ...sendParams })\n const confirmation = result.confirmations.at(createIndex - 1)!\n const transaction = result.transactions.at(createIndex - 1)!\n const deleteTransaction = result.transactions.at(-1)!\n\n Config.getLogger(sendParams?.suppressLog).warn(\n `Sent transactions ${transaction.txId()} to create app with id ${confirmation.appId} and ${deleteTransaction.txId()} to delete app with id ${\n existingApp.appId\n } from ${getAddress(createParams.sender)} account.`,\n )\n\n const appMetadata: AppMetadata = {\n appId: confirmation.appId!,\n appAddress: getApplicationAddress(confirmation.appId!),\n ...metadata,\n createdMetadata: metadata,\n createdRound: BigInt(confirmation.confirmedRound!),\n updatedRound: BigInt(confirmation.confirmedRound!),\n deleted: false,\n }\n this.updateAppLookup(createParams.sender, appMetadata)\n\n return {\n operationPerformed: 'replace',\n ...result,\n compiledApproval,\n compiledClear,\n transaction,\n confirmation,\n return: 'method' in createParams ? result.returns?.[0] : undefined,\n deleteReturn: 'method' in deleteParams ? result.returns?.at(-1) : undefined,\n ...appMetadata,\n deleteResult: { transaction: deleteTransaction, confirmation: result.confirmations.at(-1)! },\n } satisfies { operationPerformed: 'replace' } & AppMetadata &\n SendAppCreateTransactionResult & {\n deleteReturn?: ABIReturn\n deleteResult: ConfirmedTransactionResult\n }\n }\n\n // Lookup existing app metadata\n\n const apps = existingDeployments ?? (await this.getCreatorAppsByName(createParams.sender, ignoreCache))\n\n const existingApp = apps.apps[metadata.name]\n if (!existingApp || existingApp.deleted) {\n Config.getLogger(sendParams?.suppressLog).info(\n `App ${metadata.name} not found in apps created by ${getAddress(createParams.sender)}; deploying app with version ${metadata.version}.`,\n )\n\n return await createApp()\n }\n\n Config.getLogger(sendParams?.suppressLog).info(\n `Existing app ${metadata.name} found by creator ${getAddress(createParams.sender)}, with app id ${existingApp.appId} and version ${existingApp.version}.`,\n )\n\n const existingAppRecord = await this._appManager.getById(existingApp.appId)\n const existingApproval = Buffer.from(existingAppRecord.approvalProgram).toString('base64')\n const existingClear = Buffer.from(existingAppRecord.clearStateProgram).toString('base64')\n const extraPages = existingAppRecord.extraProgramPages ?? 0\n\n const newApprovalBytes = Buffer.from(approvalProgram)\n const newClearBytes = Buffer.from(clearStateProgram)\n const newApproval = newApprovalBytes.toString('base64')\n const newClear = newClearBytes.toString('base64')\n const newExtraPages = calculateExtraProgramPages(newApprovalBytes, newClearBytes)\n\n // Check for changes\n\n const isUpdate = newApproval !== existingApproval || newClear !== existingClear\n const isSchemaBreak =\n existingAppRecord.localInts < (createParams.schema?.localInts ?? 0) ||\n existingAppRecord.globalInts < (createParams.schema?.globalInts ?? 0) ||\n existingAppRecord.localByteSlices < (createParams.schema?.localByteSlices ?? 0) ||\n existingAppRecord.globalByteSlices < (createParams.schema?.globalByteSlices ?? 0) ||\n extraPages < newExtraPages\n\n if (isSchemaBreak) {\n Config.getLogger(sendParams?.suppressLog).warn(`Detected a breaking app schema change in app ${existingApp.appId}:`, {\n from: {\n globalInts: existingAppRecord.globalInts,\n globalByteSlices: existingAppRecord.globalByteSlices,\n localInts: existingAppRecord.localInts,\n localByteSlices: existingAppRecord.localByteSlices,\n extraProgramPages: extraPages,\n },\n to: { ...createParams.schema, extraProgramPages: newExtraPages },\n })\n\n if (onSchemaBreak === undefined || onSchemaBreak === 'fail' || onSchemaBreak === OnSchemaBreak.Fail) {\n throw new Error(\n 'Schema break detected and onSchemaBreak=OnSchemaBreak.Fail, stopping deployment. ' +\n 'If you want to try deleting and recreating the app then ' +\n 're-run with onSchemaBreak=OnSchemaBreak.ReplaceApp',\n )\n }\n\n if (onSchemaBreak === 'append' || onSchemaBreak === OnSchemaBreak.AppendApp) {\n Config.getLogger(sendParams?.suppressLog).info('onSchemaBreak=AppendApp, will attempt to create a new app')\n return await createApp()\n }\n\n if (existingApp.deletable) {\n Config.getLogger(sendParams?.suppressLog).info(\n 'App is deletable and onSchemaBreak=ReplaceApp, will attempt to create new app and delete old app',\n )\n } else {\n Config.getLogger(sendParams?.suppressLog).info(\n 'App is not deletable but onSchemaBreak=ReplaceApp, will attempt to delete app, delete will most likely fail',\n )\n }\n\n return await replaceApp(existingApp)\n }\n\n if (isUpdate) {\n Config.getLogger(sendParams?.suppressLog).info(\n `Detected a TEAL update in app ${existingApp.appId} for creator ${getAddress(createParams.sender)}`,\n )\n\n if (onUpdate === undefined || onUpdate === 'fail' || onUpdate === OnUpdate.Fail) {\n throw new Error('Update detected and onUpdate=Fail, stopping deployment. Try a different onUpdate value to not fail.')\n }\n\n if (onUpdate === 'append' || onUpdate === OnUpdate.AppendApp) {\n Config.getLogger(sendParams?.suppressLog).info('onUpdate=AppendApp, will attempt to create a new app')\n return await createApp()\n }\n\n if (onUpdate === 'update' || onUpdate === OnUpdate.UpdateApp) {\n if (existingApp.updatable) {\n Config.getLogger(sendParams?.suppressLog).info(`App is updatable and onUpdate=UpdateApp, updating app...`)\n } else {\n Config.getLogger(sendParams?.suppressLog).warn(\n `App is not updatable but onUpdate=UpdateApp, will attempt to update app, update will most likely fail`,\n )\n }\n\n return await updateApp(existingApp)\n }\n\n if (onUpdate === 'replace' || onUpdate === OnUpdate.ReplaceApp) {\n if (existingApp.deletable) {\n Config.getLogger(sendParams?.suppressLog).warn(\n 'App is deletable and onUpdate=ReplaceApp, creating new app and deleting old app...',\n )\n } else {\n Config.getLogger(sendParams?.suppressLog).warn(\n 'App is not deletable and onUpdate=ReplaceApp, will attempt to create new app and delete old app, delete will most likely fail',\n )\n }\n\n return await replaceApp(existingApp)\n }\n }\n\n Config.getLogger(sendParams?.suppressLog).debug('No detected changes in app, nothing to do.')\n\n return { ...existingApp, operationPerformed: 'nothing' }\n }\n\n private updateAppLookup(sender: ReadableAddress, appMetadata: AppMetadata) {\n const s = getAddress(sender).toString()\n const lookup = this._appLookups.get(s)\n if (!lookup) {\n this._appLookups.set(s, { creator: Address.fromString(s), apps: { [appMetadata.name]: appMetadata } })\n } else {\n lookup.apps[appMetadata.name] = appMetadata\n }\n }\n\n /**\n * Returns a lookup of name => app metadata (id, address, ...metadata) for all apps created by the given account that have\n * an [ARC-2](https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0002.md) `AppDeployNote` as the transaction\n * note of the app creation transaction.\n *\n * This function caches the result for the given creator account so that subsequent calls will not require an indexer lookup.\n *\n * If the `AppManager` instance wasn't created with an indexer client, this function will throw an error.\n *\n * @param creator The address of the account that is the creator of the apps you want to search for\n * @param ignoreCache Whether or not to ignore the cache and force a lookup, default: use the cache\n * @returns A name-based lookup of the app metadata\n * @example\n * ```ts\n * const result = await deployer.getCreatorAppsByName(creator)\n */\n async getCreatorAppsByName(creator: ReadableAddress, ignoreCache?: boolean): Promise<AppLookup> {\n const appLookup: Record<string, AppMetadata> = {}\n\n const creatorAddress = getAddress(creator)\n const creatorString = creatorAddress.toString()\n if (!ignoreCache && this._appLookups.has(creatorString)) {\n return this._appLookups.get(creatorString)!\n }\n\n if (!this._indexer) {\n throw new Error(`Didn't receive an indexer client when this AppManager was created, but received a call to getCreatorApps`)\n }\n\n // Extract all apps that account created\n const createdApps = (await lookupAccountCreatedApplicationByAddress(this._indexer, creatorString))\n .map((a) => {\n return { id: a.id, createdAtRound: a.createdAtRound!, deleted: a.deleted }\n })\n .sort((a, b) => Number(a.createdAtRound - b.createdAtRound))\n\n // For each app that account created (in parallel)...\n const apps = await Promise.all(\n createdApps.map(async (createdApp) => {\n // Find any app transactions for that app in the round it was created (should always just be a single creation transaction)\n const appTransactions = await searchTransactions(this._indexer!, {\n minRound: createdApp.createdAtRound,\n txType: TransactionType.AppCall,\n applicationId: createdApp.id,\n address: creatorAddress,\n addressRole: 'sender',\n notePrefix: Buffer.from(APP_DEPLOY_NOTE_DAPP).toString('base64'),\n })\n\n // Triple check the transaction is intact by filtering for the one we want:\n // * application-id is 0 when the app is first created\n // * also verify the sender to prevent a potential security risk\n const appCreationTransaction = appTransactions.transactions.filter(\n (t) => t.applicationTransaction?.applicationId === 0n && t.sender.toString() === creatorAddress.toString(),\n )[0]\n\n const latestAppUpdateTransaction = appTransactions.transactions\n .filter((t) => t.sender.toString() === creatorAddress.toString())\n .sort((a, b) =>\n a.confirmedRound === b.confirmedRound\n ? (b.intraRoundOffset! - a.intraRoundOffset!) / 10\n : Number(b.confirmedRound! - a.confirmedRound!),\n )[0]\n\n if (!appCreationTransaction?.note)\n // No note; ignoring\n return null\n\n return { createdApp, appCreationTransaction, latestAppUpdateTransaction }\n }),\n )\n\n apps\n .filter((a) => a !== null)\n .forEach((a) => {\n const { createdApp, appCreationTransaction, latestAppUpdateTransaction } = a!\n\n const parseNote = (note?: string) => {\n if (!note) {\n // No note; ignoring...\n return\n }\n\n if (!note.startsWith(`${APP_DEPLOY_NOTE_DAPP}:j{`))\n // Clearly not APP_DEPLOY JSON; ignoring...\n return\n\n return JSON.parse(note.substring(APP_DEPLOY_NOTE_DAPP.length + 2)) as AppDeployMetadata\n }\n\n try {\n const creationNote = parseNote(\n appCreationTransaction.note ? Buffer.from(appCreationTransaction.note).toString('utf-8') : undefined,\n )\n const updateNote = parseNote(\n latestAppUpdateTransaction.note ? Buffer.from(latestAppUpdateTransaction.note).toString('utf-8') : undefined,\n )\n if (creationNote?.name) {\n appLookup[creationNote.name] = {\n appId: createdApp.id,\n appAddress: getApplicationAddress(createdApp.id),\n createdMetadata: creationNote,\n createdRound: appCreationTransaction.confirmedRound ?? 0n,\n ...(updateNote ?? creationNote),\n updatedRound: latestAppUpdateTransaction?.confirmedRound ?? 0n,\n deleted: createdApp.deleted ?? false,\n }\n }\n } catch (e) {\n Config.logger.warn(\n `Received error trying to retrieve app with ${createdApp.id} for creator ${creatorAddress}; failing silently`,\n e,\n )\n return\n }\n })\n\n const lookup = {\n creator: creatorAddress,\n apps: appLookup,\n }\n\n this._appLookups.set(creatorString, lookup)\n\n return lookup\n }\n}\n"],"mappings":"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"}
|