@algorandfoundation/algokit-utils 10.0.0-alpha.5 → 10.0.0-alpha.6
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/algod-client/index.d.ts +1 -4
- package/package.json +1 -1
- package/packages/algod_client/src/models/simulate-unnamed-resources-accessed.d.ts +3 -5
- package/packages/algod_client/src/models/simulate-unnamed-resources-accessed.js +4 -6
- package/packages/algod_client/src/models/simulate-unnamed-resources-accessed.js.map +1 -1
- package/packages/algod_client/src/models/simulate-unnamed-resources-accessed.mjs +3 -5
- package/packages/algod_client/src/models/simulate-unnamed-resources-accessed.mjs.map +1 -1
- package/packages/common/src/json.mjs +2 -2
- package/packages/common/src/json.mjs.map +1 -1
- package/packages/sdk/src/utils/utils.mjs +2 -2
- package/packages/sdk/src/utils/utils.mjs.map +1 -1
- package/packages/transact/src/multisig.d.ts +2 -2
- package/packages/transact/src/multisig.js +15 -15
- package/packages/transact/src/multisig.js.map +1 -1
- package/packages/transact/src/multisig.mjs +15 -15
- package/packages/transact/src/multisig.mjs.map +1 -1
- package/packages/transact/src/transactions/app-call.d.ts +8 -8
- package/packages/transact/src/transactions/app-call.js.map +1 -1
- package/packages/transact/src/transactions/app-call.mjs.map +1 -1
- package/packages/transact/src/transactions/reference-types-meta.d.ts +26 -0
- package/packages/transact/src/transactions/reference-types-meta.js +71 -0
- package/packages/transact/src/transactions/reference-types-meta.js.map +1 -0
- package/packages/transact/src/transactions/reference-types-meta.mjs +69 -0
- package/packages/transact/src/transactions/reference-types-meta.mjs.map +1 -0
- package/packages/transact/src/transactions/transaction-meta.js +22 -22
- package/packages/transact/src/transactions/transaction-meta.js.map +1 -1
- package/packages/transact/src/transactions/transaction-meta.mjs +22 -22
- package/packages/transact/src/transactions/transaction-meta.mjs.map +1 -1
- package/transact/index.d.ts +3 -2
- package/transact/index.js +4 -0
- package/transact/index.mjs +2 -1
- package/transactions/app-call.d.ts +2 -2
- package/transactions/app-call.js +15 -15
- package/transactions/app-call.js.map +1 -1
- package/transactions/app-call.mjs +15 -15
- package/transactions/app-call.mjs.map +1 -1
- package/transactions/asset-config.d.ts +1 -1
- package/transactions/asset-config.js +1 -1
- package/transactions/asset-config.js.map +1 -1
- package/transactions/asset-config.mjs +1 -1
- package/transactions/asset-config.mjs.map +1 -1
- package/types/algorand-client-transaction-creator.d.ts +80 -80
- package/types/algorand-client-transaction-sender.d.ts +83 -83
- package/types/app-client.d.ts +145 -145
- package/types/app-factory.d.ts +70 -70
- package/types/app-manager.js +5 -5
- package/types/app-manager.js.map +1 -1
- package/types/app-manager.mjs +5 -5
- package/types/app-manager.mjs.map +1 -1
- package/types/composer.js +3 -3
- package/types/composer.js.map +1 -1
- package/types/composer.mjs +3 -3
- package/types/composer.mjs.map +1 -1
- package/packages/algod_client/src/models/application-local-reference.d.ts +0 -20
- package/packages/algod_client/src/models/application-local-reference.js +0 -23
- package/packages/algod_client/src/models/application-local-reference.js.map +0 -1
- package/packages/algod_client/src/models/application-local-reference.mjs +0 -23
- package/packages/algod_client/src/models/application-local-reference.mjs.map +0 -1
- package/packages/algod_client/src/models/asset-holding-reference.d.ts +0 -20
- package/packages/algod_client/src/models/asset-holding-reference.js +0 -23
- package/packages/algod_client/src/models/asset-holding-reference.js.map +0 -1
- package/packages/algod_client/src/models/asset-holding-reference.mjs +0 -23
- package/packages/algod_client/src/models/asset-holding-reference.mjs.map +0 -1
- package/packages/algod_client/src/models/box-reference.d.ts +0 -17
- package/packages/algod_client/src/models/box-reference.js +0 -23
- package/packages/algod_client/src/models/box-reference.js.map +0 -1
- package/packages/algod_client/src/models/box-reference.mjs +0 -23
- package/packages/algod_client/src/models/box-reference.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"multisig.mjs","names":["mergedSubsignatures: MultisigSubsignature[]","msig: MultisigSignature","authAddress: Address | undefined","newSubsigs: MultisigSubsignature[]","multisigAddress: typeof addressFromMultisigPreImgAddrs","signedMsigTxns: Uint8Array[]"],"sources":["../../../../packages/transact/src/multisig.ts"],"sourcesContent":["import {\n Address,\n ALGORAND_ADDRESS_BYTE_LENGTH,\n ALGORAND_CHECKSUM_BYTE_LENGTH,\n arrayEqual,\n decodeMsgpack,\n getAddress,\n hash,\n PUBLIC_KEY_BYTE_LENGTH,\n SIGNATURE_BYTE_LENGTH,\n} from '@algorandfoundation/algokit-common'\nimport { AddressWithDelegatedLsigSigner, AddressWithTransactionSigner, TransactionSigner } from './signer'\nimport {\n decodeSignedTransaction,\n encodeSignedTransaction,\n MultisigSignature,\n MultisigSubsignature,\n SignedTransaction,\n} from './transactions/signed-transaction'\nimport { multiSignatureCodec } from './transactions/signed-transaction-meta'\nimport { Transaction } from './transactions/transaction'\n\n/**\n * Creates an empty multisignature signature from a list of participant public keys.\n */\nexport function newMultisigSignature(version: number, threshold: number, participants: Uint8Array[]): MultisigSignature {\n if (version === 0) {\n throw new Error('Version cannot be zero')\n }\n if (participants.length === 0) {\n throw new Error('Participants cannot be empty')\n }\n if (threshold === 0 || threshold > participants.length) {\n throw new Error('Threshold must be greater than zero and less than or equal to the number of participants')\n }\n\n return {\n version,\n threshold,\n subsignatures: participants.map((publicKey) => ({ publicKey })),\n }\n}\n\n/**\n * Returns the list of participant public keys from a multisignature signature.\n */\nexport function participantsFromMultisigSignature(multisigSignature: MultisigSignature): Uint8Array[] {\n return multisigSignature.subsignatures.map((subsig) => subsig.publicKey)\n}\n\nconst toPublicKeys = (addrs: Array<string | Address>): Uint8Array[] => addrs.map((addr) => getAddress(addr).publicKey)\n\n/**\n * Returns the address of the multisignature account.\n */\nexport function addressFromMultisigSignature(multisigSignature: MultisigSignature): Address {\n return addressFromMultisigPreImg({\n version: multisigSignature.version,\n threshold: multisigSignature.threshold,\n pks: multisigSignature.subsignatures.map((subsig) => subsig.publicKey),\n })\n}\n\n/**\n * Applies a subsignature for a participant to a multisignature signature, replacing any existing signature.\n *\n * This method applies the signature to ALL instances of the given public key (to support weighted multisig).\n * Since ed25519 signatures are deterministic, there's only one valid signature for a given message and public key.\n */\nexport function applyMultisigSubsignature(\n multisigSignature: MultisigSignature,\n participant: Uint8Array,\n signature: Uint8Array,\n): MultisigSignature {\n let found = false\n const newSubsignatures = multisigSignature.subsignatures.map((subsig) => {\n if (arrayEqual(subsig.publicKey, participant)) {\n found = true\n return { ...subsig, signature }\n }\n return subsig\n })\n\n if (!found) {\n throw new Error('Public key not found in multisig signature')\n }\n\n return {\n ...multisigSignature,\n subsignatures: newSubsignatures,\n }\n}\n\n/**\n * Merges two multisignature signatures, replacing signatures in the first with those from the second where present.\n * For each participant, the resulting signature will be taken from the second multisig if present, otherwise from the first.\n */\nexport function mergeMultisignatures(multisigSignatureA: MultisigSignature, multisigSignatureB: MultisigSignature): MultisigSignature {\n if (multisigSignatureA.version !== multisigSignatureB.version) {\n throw new Error('Cannot merge multisig signatures with different versions')\n }\n if (multisigSignatureA.threshold !== multisigSignatureB.threshold) {\n throw new Error('Cannot merge multisig signatures with different thresholds')\n }\n\n // Check participants match exactly (same public keys in same order)\n const participantsA = participantsFromMultisigSignature(multisigSignatureA)\n const participantsB = participantsFromMultisigSignature(multisigSignatureB)\n const participantsMatch =\n participantsA.length === participantsB.length && participantsA.every((pk, i) => arrayEqual(pk, participantsB[i]))\n if (!participantsMatch) {\n throw new Error('Cannot merge multisig signatures with different participants')\n }\n\n const mergedSubsignatures: MultisigSubsignature[] = multisigSignatureA.subsignatures.map((s1, index) => {\n const s2 = multisigSignatureB.subsignatures[index]\n return {\n publicKey: s1.publicKey,\n signature: s2.signature || s1.signature, // Prefer s2, fall back to s1\n }\n })\n\n return {\n version: multisigSignatureA.version,\n threshold: multisigSignatureA.threshold,\n subsignatures: mergedSubsignatures,\n }\n}\n\n// Convert \"MultisigAddr\" UTF-8 to byte array\nconst MULTISIG_PREIMG2ADDR_PREFIX = new Uint8Array([77, 117, 108, 116, 105, 115, 105, 103, 65, 100, 100, 114])\n\nconst INVALID_MSIG_VERSION_ERROR_MSG = 'invalid multisig version'\nconst INVALID_MSIG_THRESHOLD_ERROR_MSG = 'bad multisig threshold'\nconst INVALID_MSIG_PK_ERROR_MSG = 'bad multisig public key - wrong length'\nconst UNEXPECTED_PK_LEN_ERROR_MSG = 'nacl public key length is not 32 bytes'\n\nexport const MULTISIG_MERGE_LESSTHANTWO_ERROR_MSG = 'Not enough multisig transactions to merge. Need at least two'\nexport const MULTISIG_MERGE_MISMATCH_ERROR_MSG = 'Cannot merge txs. txIDs differ'\nexport const MULTISIG_MERGE_MISMATCH_AUTH_ADDR_MSG = 'Cannot merge txs. Auth addrs differ'\nexport const MULTISIG_MERGE_WRONG_PREIMAGE_ERROR_MSG = 'Cannot merge txs. Multisig preimages differ'\nexport const MULTISIG_MERGE_SIG_MISMATCH_ERROR_MSG = 'Cannot merge txs. subsigs are mismatched.'\nexport const MULTISIG_NO_MUTATE_ERROR_MSG = 'Cannot mutate a multisig field as it would invalidate all existing signatures.'\nexport const MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG = 'Cannot sign a multisig transaction using `signTxn`. Use `partialSignTxn` instead.'\nexport const MULTISIG_SIGNATURE_LENGTH_ERROR_MSG = 'Cannot add multisig signature. Signature is not of the correct length.'\nconst MULTISIG_KEY_NOT_EXIST_ERROR_MSG = 'Key does not exist'\n\n/**\n * creates a raw, multisig transaction blob without any signatures.\n * @param txn - the actual transaction.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param pks - ordered list of public keys in this multisig\n * @returns encoded multisig blob\n */\nexport function createMultisigTransaction(txn: Transaction, { version, threshold, addrs }: MultisigMetadata) {\n // construct the appendable multisigned transaction format\n const pks = toPublicKeys(addrs)\n const subsignatures: MultisigSubsignature[] = pks.map((pk) => ({\n publicKey: pk,\n signature: undefined,\n }))\n\n const msig: MultisigSignature = {\n version,\n threshold,\n subsignatures,\n }\n\n // if the address of this multisig is different from the transaction sender,\n // we need to add the auth-addr field\n const msigAddr = addressFromMultisigPreImg({\n version,\n threshold,\n pks,\n })\n let authAddress: Address | undefined\n if (!msigAddr.equals(txn.sender)) {\n authAddress = msigAddr\n }\n\n const signedTxn: SignedTransaction = {\n txn: txn,\n msig: msig,\n authAddress,\n }\n\n return encodeSignedTransaction(signedTxn)\n}\n\ninterface MultisigOptions {\n rawSig: Uint8Array\n myPk: Uint8Array\n}\n\ninterface MultisigMetadataWithPks extends Omit<MultisigMetadata, 'addrs'> {\n pks: Uint8Array[]\n}\n\n/**\n * creates a multisig transaction blob with an included signature.\n * @param txn - the actual transaction to sign.\n * @param rawSig - a Uint8Array raw signature of that transaction\n * @param myPk - a public key that corresponds with rawSig\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param pks - ordered list of public keys in this multisig\n * @returns encoded multisig blob\n */\nfunction createMultisigTransactionWithSignature(\n txn: Transaction,\n { rawSig, myPk }: MultisigOptions,\n { version, threshold, pks }: MultisigMetadataWithPks,\n): Uint8Array {\n // Create an empty encoded multisig transaction\n const encodedMsig = createMultisigTransaction(txn, {\n version,\n threshold,\n addrs: pks.map((pk) => new Address(pk)),\n })\n // note: this is not signed yet, but will be shortly\n const signedTxn = decodeSignedTransaction(encodedMsig)\n\n let keyExist = false\n\n // append the multisig signature to the corresponding public key in the multisig blob\n const updatedSubsigs = signedTxn.msig!.subsignatures.map((subsig) => {\n if (arrayEqual(subsig.publicKey, myPk)) {\n keyExist = true\n return { ...subsig, signature: rawSig }\n }\n return subsig\n })\n\n if (!keyExist) {\n throw new Error(MULTISIG_KEY_NOT_EXIST_ERROR_MSG)\n }\n\n const updatedSignedTxn: SignedTransaction = {\n ...signedTxn,\n msig: {\n ...signedTxn.msig!,\n subsignatures: updatedSubsigs,\n },\n }\n\n return encodeSignedTransaction(updatedSignedTxn)\n}\n\n/**\n * takes a list of multisig transaction blobs, and merges them.\n * @param multisigTxnBlobs - a list of blobs representing encoded multisig txns\n * @returns typed array msg-pack encoded multisig txn\n */\nexport function mergeMultisigTransactions(multisigTxnBlobs: Uint8Array[]) {\n if (multisigTxnBlobs.length < 2) {\n throw new Error(MULTISIG_MERGE_LESSTHANTWO_ERROR_MSG)\n }\n const refSigTx = decodeSignedTransaction(multisigTxnBlobs[0])\n if (!refSigTx.msig) {\n throw new Error('Invalid multisig transaction, multisig structure missing at index 0')\n }\n const refTxID = refSigTx.txn.txId()\n const refAuthAddr = refSigTx.authAddress\n const refPreImage = {\n version: refSigTx.msig.version,\n threshold: refSigTx.msig.threshold,\n pks: refSigTx.msig.subsignatures.map((subsig) => subsig.publicKey),\n }\n const refMsigAddr = addressFromMultisigPreImg(refPreImage)\n\n const newSubsigs: MultisigSubsignature[] = refSigTx.msig.subsignatures.map((sig) => ({ ...sig }))\n for (let i = 1; i < multisigTxnBlobs.length; i++) {\n const unisig = decodeSignedTransaction(multisigTxnBlobs[i])\n if (!unisig.msig) {\n throw new Error(`Invalid multisig transaction, multisig structure missing at index ${i}`)\n }\n\n if (unisig.txn.txId() !== refTxID) {\n throw new Error(MULTISIG_MERGE_MISMATCH_ERROR_MSG)\n }\n\n const authAddr = unisig.authAddress\n if (refAuthAddr !== authAddr) {\n throw new Error(MULTISIG_MERGE_MISMATCH_AUTH_ADDR_MSG)\n }\n\n // check multisig has same preimage as reference\n if (unisig.msig.subsignatures.length !== refSigTx.msig.subsignatures.length) {\n throw new Error(MULTISIG_MERGE_WRONG_PREIMAGE_ERROR_MSG)\n }\n const preimg: MultisigMetadataWithPks = {\n version: unisig.msig.version,\n threshold: unisig.msig.threshold,\n pks: unisig.msig.subsignatures.map((subsig) => subsig.publicKey),\n }\n const msgigAddr = addressFromMultisigPreImg(preimg)\n if (refMsigAddr.toString() !== msgigAddr.toString()) {\n throw new Error(MULTISIG_MERGE_WRONG_PREIMAGE_ERROR_MSG)\n }\n\n // now, we can merge\n unisig.msig.subsignatures.forEach((uniSubsig, index) => {\n if (!uniSubsig.signature) return\n const current = newSubsigs[index]\n if (current.signature && !arrayEqual(uniSubsig.signature, current.signature)) {\n // mismatch\n throw new Error(MULTISIG_MERGE_SIG_MISMATCH_ERROR_MSG)\n }\n current.signature = uniSubsig.signature\n })\n }\n\n const msig: MultisigSignature = {\n version: refSigTx.msig.version,\n threshold: refSigTx.msig.threshold,\n subsignatures: newSubsigs,\n }\n\n const signedTxn: SignedTransaction = {\n txn: refSigTx.txn,\n msig: msig,\n authAddress: refAuthAddr,\n }\n\n return encodeSignedTransaction(signedTxn)\n}\n\n/**\n * Partially signs this transaction with an external raw multisig signature and returns\n * a partially-signed multisig transaction, encoded with msgpack as a typed array.\n * @param transaction - The transaction to sign\n * @param metadata - multisig metadata\n * @param signerAddr - address of the signer\n * @param signature - raw multisig signature\n * @returns an encoded, partially signed multisig transaction.\n */\nfunction partialSignWithMultisigSignature(\n transaction: Transaction,\n metadata: MultisigMetadataWithPks,\n signerAddr: string | Address,\n signature: Uint8Array,\n) {\n if (signature.length != SIGNATURE_BYTE_LENGTH) {\n throw new Error(MULTISIG_SIGNATURE_LENGTH_ERROR_MSG)\n }\n const signerAddressObj = typeof signerAddr === 'string' ? Address.fromString(signerAddr) : signerAddr\n return createMultisigTransactionWithSignature(\n transaction,\n {\n rawSig: signature,\n myPk: signerAddressObj.publicKey,\n },\n metadata,\n )\n}\n\n/**\n * Takes a multisig transaction blob, and appends a given raw signature to it.\n * This makes it possible to compile a multisig signature using only raw signatures from external methods.\n * @param multisigTxnBlob - an encoded multisig txn. Supports non-payment txn types.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param addrs - a list of Algorand addresses representing possible signers for this multisig. Order is important.\n * @param signerAddr - address of the signer\n * @param signature - raw multisig signature\n * @returns object containing txID, and blob representing encoded multisig txn\n */\nexport function appendSignRawMultisigSignature(\n multisigTxnBlob: Uint8Array,\n { version, threshold, addrs }: MultisigMetadata,\n signerAddr: string | Address,\n signature: Uint8Array,\n) {\n const pks = toPublicKeys(addrs)\n // obtain underlying txn, sign it, and merge it\n const multisigTxObj = decodeSignedTransaction(multisigTxnBlob)\n const partialSignedBlob = partialSignWithMultisigSignature(multisigTxObj.txn, { version, threshold, pks }, signerAddr, signature)\n return {\n txID: multisigTxObj.txn.txId(),\n blob: mergeMultisigTransactions([multisigTxnBlob, partialSignedBlob]),\n }\n}\n\n/**\n * Takes multisig parameters and returns a 32 byte typed array public key,\n * representing an address that identifies the \"exact group, version, and public keys\" that are required for signing.\n * Hash(\"MultisigAddr\" || version uint8 || threshold uint8 || PK1 || PK2 || ...)\n * Encoding this output yields a human readable address.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param pks - array of typed array public keys\n */\nexport function addressFromMultisigPreImg({\n version,\n threshold,\n pks,\n}: Omit<MultisigMetadata, 'addrs'> & {\n pks: Uint8Array[]\n}): Address {\n if (version > 255 || version < 0) {\n // ^ a tad redundant, but in case in the future version != 1, still check for uint8\n throw new Error(`${INVALID_MSIG_VERSION_ERROR_MSG}: ${version}`)\n }\n if (threshold === 0 || pks.length === 0 || threshold > pks.length || threshold > 255) {\n throw new Error(INVALID_MSIG_THRESHOLD_ERROR_MSG)\n }\n const pkLen = ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH\n if (pkLen !== PUBLIC_KEY_BYTE_LENGTH) {\n throw new Error(UNEXPECTED_PK_LEN_ERROR_MSG)\n }\n const merged = new Uint8Array(MULTISIG_PREIMG2ADDR_PREFIX.length + 2 + pkLen * pks.length)\n merged.set(MULTISIG_PREIMG2ADDR_PREFIX, 0)\n merged.set([version], MULTISIG_PREIMG2ADDR_PREFIX.length)\n merged.set([threshold], MULTISIG_PREIMG2ADDR_PREFIX.length + 1)\n for (let i = 0; i < pks.length; i++) {\n if (pks[i].length !== pkLen) {\n throw new Error(INVALID_MSIG_PK_ERROR_MSG)\n }\n merged.set(pks[i], MULTISIG_PREIMG2ADDR_PREFIX.length + 2 + i * pkLen)\n }\n return new Address(Uint8Array.from(hash(merged)))\n}\n\n/**\n * Takes multisig parameters and returns a human readable Algorand address.\n * This is equivalent to fromMultisigPreImg, but interfaces with encoded addresses.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param addrs - array of encoded addresses\n */\nexport function addressFromMultisigPreImgAddrs({ version, threshold, addrs }: MultisigMetadata): Address {\n return addressFromMultisigPreImg({\n version,\n threshold,\n pks: toPublicKeys(addrs),\n })\n}\n\n/**\n * Takes multisig metadata (preimage) and returns the corresponding human readable Algorand address.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param addrs - list of Algorand addresses\n */\nexport const multisigAddress: typeof addressFromMultisigPreImgAddrs = addressFromMultisigPreImgAddrs\n\nexport interface MultisigMetadata {\n /**\n * Multisig version\n */\n version: number\n\n /**\n * Multisig threshold value. Authorization requires a subset of signatures,\n * equal to or greater than the threshold value.\n */\n threshold: number\n\n /**\n * A list of Algorand addresses representing possible signers for this multisig. Order is important.\n */\n addrs: Array<Address>\n}\n\n/** Account wrapper that supports partial or full multisig signing. */\nexport class MultisigAccount implements AddressWithTransactionSigner {\n _params: MultisigMetadata\n _subSigners: (AddressWithTransactionSigner & AddressWithDelegatedLsigSigner)[]\n _addr: Address\n _signer: TransactionSigner\n\n /** The parameters for the multisig account */\n get params(): Readonly<MultisigMetadata> {\n return this._params\n }\n\n /** The list of accounts that are present to sign transactions or lsigs */\n get subSigners() {\n return this._subSigners\n }\n\n /** The address of the multisig account */\n get addr(): Readonly<Address> {\n return this._addr\n }\n\n /** The transaction signer for the multisig account */\n get signer(): TransactionSigner {\n return this._signer\n }\n\n constructor(multisigParams: MultisigMetadata, subSigners: (AddressWithTransactionSigner & AddressWithDelegatedLsigSigner)[]) {\n this._params = multisigParams\n this._subSigners = subSigners\n this._addr = multisigAddress(multisigParams)\n this._signer = async (txns: Transaction[], indexesToSign: number[]): Promise<Uint8Array[]> => {\n const txnsToSign = txns.filter((_, index) => indexesToSign.includes(index))\n const signedMsigTxns: Uint8Array[] = []\n\n for (const txn of txnsToSign) {\n let signedMsigTxn = createMultisigTransaction(txn, this._params)\n\n for (const subSigner of this.subSigners) {\n const stxn = (await subSigner.signer([txn], [0]))[0]\n const sig = decodeSignedTransaction(stxn).sig\n\n if (!sig) {\n throw new Error(\n `Signer for address ${subSigner.addr.toString()} did not produce a valid signature when signing ${txn.txId()} for multisig account ${this._addr.toString()}`,\n )\n }\n\n signedMsigTxn = appendSignRawMultisigSignature(signedMsigTxn, this._params, subSigner.addr, sig).blob\n }\n\n signedMsigTxns.push(signedMsigTxn)\n }\n\n return signedMsigTxns\n }\n }\n}\n/**\n * Decodes MsgPack bytes into a multi signature.\n *\n * @param encodedMultiSignature - The MsgPack encoded multi signature\n * @returns The decoded MultisigSignature or an error if decoding fails.\n */\nexport function decodeMultiSignature(encodedMultiSignature: Uint8Array): MultisigSignature {\n const decodedData = decodeMsgpack(encodedMultiSignature)\n return multiSignatureCodec.decode(decodedData, 'msgpack')\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"multisig.mjs","names":["mergedSubsignatures: MultisigSubsignature[]","msig: MultisigSignature","authAddress: Address | undefined","newSubsigs: MultisigSubsignature[]","multisigAddress: typeof addressFromMultisigPreImgAddrs","signedMsigTxns: Uint8Array[]"],"sources":["../../../../packages/transact/src/multisig.ts"],"sourcesContent":["import {\n Address,\n ALGORAND_ADDRESS_BYTE_LENGTH,\n ALGORAND_CHECKSUM_BYTE_LENGTH,\n arrayEqual,\n decodeMsgpack,\n getAddress,\n hash,\n PUBLIC_KEY_BYTE_LENGTH,\n SIGNATURE_BYTE_LENGTH,\n} from '@algorandfoundation/algokit-common'\nimport { AddressWithDelegatedLsigSigner, AddressWithTransactionSigner, TransactionSigner } from './signer'\nimport {\n decodeSignedTransaction,\n encodeSignedTransaction,\n MultisigSignature,\n MultisigSubsignature,\n SignedTransaction,\n} from './transactions/signed-transaction'\nimport { multiSignatureCodec } from './transactions/signed-transaction-meta'\nimport { Transaction } from './transactions/transaction'\n\n/**\n * Creates an empty multisignature signature from a list of participant public keys.\n */\nexport function newMultisigSignature(version: number, threshold: number, participants: Uint8Array[]): MultisigSignature {\n if (version === 0) {\n throw new Error('Version cannot be zero')\n }\n if (participants.length === 0) {\n throw new Error('Participants cannot be empty')\n }\n if (threshold === 0 || threshold > participants.length) {\n throw new Error('Threshold must be greater than zero and less than or equal to the number of participants')\n }\n\n return {\n version,\n threshold,\n subsignatures: participants.map((publicKey) => ({ publicKey })),\n }\n}\n\n/**\n * Returns the list of participant public keys from a multisignature signature.\n */\nexport function participantsFromMultisigSignature(multisigSignature: MultisigSignature): Uint8Array[] {\n return multisigSignature.subsignatures.map((subsig) => subsig.publicKey)\n}\n\nconst toPublicKeys = (addrs: Array<string | Address>): Uint8Array[] => addrs.map((addr) => getAddress(addr).publicKey)\n\n/**\n * Returns the address of the multisignature account.\n */\nexport function addressFromMultisigSignature(multisigSignature: MultisigSignature): Address {\n return addressFromMultisigPreImg({\n version: multisigSignature.version,\n threshold: multisigSignature.threshold,\n publicKeys: multisigSignature.subsignatures.map((subsig) => subsig.publicKey),\n })\n}\n\n/**\n * Applies a subsignature for a participant to a multisignature signature, replacing any existing signature.\n *\n * This method applies the signature to ALL instances of the given public key (to support weighted multisig).\n * Since ed25519 signatures are deterministic, there's only one valid signature for a given message and public key.\n */\nexport function applyMultisigSubsignature(\n multisigSignature: MultisigSignature,\n participant: Uint8Array,\n signature: Uint8Array,\n): MultisigSignature {\n let found = false\n const newSubsignatures = multisigSignature.subsignatures.map((subsig) => {\n if (arrayEqual(subsig.publicKey, participant)) {\n found = true\n return { ...subsig, signature }\n }\n return subsig\n })\n\n if (!found) {\n throw new Error('Public key not found in multisig signature')\n }\n\n return {\n ...multisigSignature,\n subsignatures: newSubsignatures,\n }\n}\n\n/**\n * Merges two multisignature signatures, replacing signatures in the first with those from the second where present.\n * For each participant, the resulting signature will be taken from the second multisig if present, otherwise from the first.\n */\nexport function mergeMultisignatures(multisigSignatureA: MultisigSignature, multisigSignatureB: MultisigSignature): MultisigSignature {\n if (multisigSignatureA.version !== multisigSignatureB.version) {\n throw new Error('Cannot merge multisig signatures with different versions')\n }\n if (multisigSignatureA.threshold !== multisigSignatureB.threshold) {\n throw new Error('Cannot merge multisig signatures with different thresholds')\n }\n\n // Check participants match exactly (same public keys in same order)\n const participantsA = participantsFromMultisigSignature(multisigSignatureA)\n const participantsB = participantsFromMultisigSignature(multisigSignatureB)\n const participantsMatch =\n participantsA.length === participantsB.length && participantsA.every((pk, i) => arrayEqual(pk, participantsB[i]))\n if (!participantsMatch) {\n throw new Error('Cannot merge multisig signatures with different participants')\n }\n\n const mergedSubsignatures: MultisigSubsignature[] = multisigSignatureA.subsignatures.map((s1, index) => {\n const s2 = multisigSignatureB.subsignatures[index]\n return {\n publicKey: s1.publicKey,\n signature: s2.signature || s1.signature, // Prefer s2, fall back to s1\n }\n })\n\n return {\n version: multisigSignatureA.version,\n threshold: multisigSignatureA.threshold,\n subsignatures: mergedSubsignatures,\n }\n}\n\n// Convert \"MultisigAddr\" UTF-8 to byte array\nconst MULTISIG_PREIMG2ADDR_PREFIX = new Uint8Array([77, 117, 108, 116, 105, 115, 105, 103, 65, 100, 100, 114])\n\nconst INVALID_MSIG_VERSION_ERROR_MSG = 'invalid multisig version'\nconst INVALID_MSIG_THRESHOLD_ERROR_MSG = 'bad multisig threshold'\nconst INVALID_MSIG_PK_ERROR_MSG = 'bad multisig public key - wrong length'\nconst UNEXPECTED_PK_LEN_ERROR_MSG = 'nacl public key length is not 32 bytes'\n\nexport const MULTISIG_MERGE_LESSTHANTWO_ERROR_MSG = 'Not enough multisig transactions to merge. Need at least two'\nexport const MULTISIG_MERGE_MISMATCH_ERROR_MSG = 'Cannot merge txs. txIDs differ'\nexport const MULTISIG_MERGE_MISMATCH_AUTH_ADDR_MSG = 'Cannot merge txs. Auth addrs differ'\nexport const MULTISIG_MERGE_WRONG_PREIMAGE_ERROR_MSG = 'Cannot merge txs. Multisig preimages differ'\nexport const MULTISIG_MERGE_SIG_MISMATCH_ERROR_MSG = 'Cannot merge txs. subsigs are mismatched.'\nexport const MULTISIG_NO_MUTATE_ERROR_MSG = 'Cannot mutate a multisig field as it would invalidate all existing signatures.'\nexport const MULTISIG_USE_PARTIAL_SIGN_ERROR_MSG = 'Cannot sign a multisig transaction using `signTxn`. Use `partialSignTxn` instead.'\nexport const MULTISIG_SIGNATURE_LENGTH_ERROR_MSG = 'Cannot add multisig signature. Signature is not of the correct length.'\nconst MULTISIG_KEY_NOT_EXIST_ERROR_MSG = 'Key does not exist'\n\n/**\n * creates a raw, multisig transaction blob without any signatures.\n * @param txn - the actual transaction.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param pks - ordered list of public keys in this multisig\n * @returns encoded multisig blob\n */\nexport function createMultisigTransaction(txn: Transaction, { version, threshold, addrs }: MultisigMetadata) {\n // construct the appendable multisigned transaction format\n const pks = toPublicKeys(addrs)\n const subsignatures: MultisigSubsignature[] = pks.map((pk) => ({\n publicKey: pk,\n signature: undefined,\n }))\n\n const msig: MultisigSignature = {\n version,\n threshold,\n subsignatures,\n }\n\n // if the address of this multisig is different from the transaction sender,\n // we need to add the auth-addr field\n const msigAddr = addressFromMultisigPreImg({\n version,\n threshold,\n publicKeys: pks,\n })\n let authAddress: Address | undefined\n if (!msigAddr.equals(txn.sender)) {\n authAddress = msigAddr\n }\n\n const signedTxn: SignedTransaction = {\n txn: txn,\n msig: msig,\n authAddress,\n }\n\n return encodeSignedTransaction(signedTxn)\n}\n\ninterface MultisigOptions {\n rawSig: Uint8Array\n myPk: Uint8Array\n}\n\ninterface MultisigMetadataWithPublicKeys extends Omit<MultisigMetadata, 'addrs'> {\n publicKeys: Uint8Array[]\n}\n\n/**\n * creates a multisig transaction blob with an included signature.\n * @param txn - the actual transaction to sign.\n * @param rawSig - a Uint8Array raw signature of that transaction\n * @param myPk - a public key that corresponds with rawSig\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param pks - ordered list of public keys in this multisig\n * @returns encoded multisig blob\n */\nfunction createMultisigTransactionWithSignature(\n txn: Transaction,\n { rawSig, myPk }: MultisigOptions,\n { version, threshold, publicKeys }: MultisigMetadataWithPublicKeys,\n): Uint8Array {\n // Create an empty encoded multisig transaction\n const encodedMsig = createMultisigTransaction(txn, {\n version,\n threshold,\n addrs: publicKeys.map((pk) => new Address(pk)),\n })\n // note: this is not signed yet, but will be shortly\n const signedTxn = decodeSignedTransaction(encodedMsig)\n\n let keyExist = false\n\n // append the multisig signature to the corresponding public key in the multisig blob\n const updatedSubsigs = signedTxn.msig!.subsignatures.map((subsig) => {\n if (arrayEqual(subsig.publicKey, myPk)) {\n keyExist = true\n return { ...subsig, signature: rawSig }\n }\n return subsig\n })\n\n if (!keyExist) {\n throw new Error(MULTISIG_KEY_NOT_EXIST_ERROR_MSG)\n }\n\n const updatedSignedTxn: SignedTransaction = {\n ...signedTxn,\n msig: {\n ...signedTxn.msig!,\n subsignatures: updatedSubsigs,\n },\n }\n\n return encodeSignedTransaction(updatedSignedTxn)\n}\n\n/**\n * takes a list of multisig transaction blobs, and merges them.\n * @param multisigTxnBlobs - a list of blobs representing encoded multisig txns\n * @returns typed array msg-pack encoded multisig txn\n */\nexport function mergeMultisigTransactions(multisigTxnBlobs: Uint8Array[]) {\n if (multisigTxnBlobs.length < 2) {\n throw new Error(MULTISIG_MERGE_LESSTHANTWO_ERROR_MSG)\n }\n const refSigTx = decodeSignedTransaction(multisigTxnBlobs[0])\n if (!refSigTx.msig) {\n throw new Error('Invalid multisig transaction, multisig structure missing at index 0')\n }\n const refTxID = refSigTx.txn.txId()\n const refAuthAddr = refSigTx.authAddress\n const refPreImage = {\n version: refSigTx.msig.version,\n threshold: refSigTx.msig.threshold,\n publicKeys: refSigTx.msig.subsignatures.map((subsig) => subsig.publicKey),\n }\n const refMsigAddr = addressFromMultisigPreImg(refPreImage)\n\n const newSubsigs: MultisigSubsignature[] = refSigTx.msig.subsignatures.map((sig) => ({ ...sig }))\n for (let i = 1; i < multisigTxnBlobs.length; i++) {\n const unisig = decodeSignedTransaction(multisigTxnBlobs[i])\n if (!unisig.msig) {\n throw new Error(`Invalid multisig transaction, multisig structure missing at index ${i}`)\n }\n\n if (unisig.txn.txId() !== refTxID) {\n throw new Error(MULTISIG_MERGE_MISMATCH_ERROR_MSG)\n }\n\n const authAddr = unisig.authAddress\n if (refAuthAddr !== authAddr) {\n throw new Error(MULTISIG_MERGE_MISMATCH_AUTH_ADDR_MSG)\n }\n\n // check multisig has same preimage as reference\n if (unisig.msig.subsignatures.length !== refSigTx.msig.subsignatures.length) {\n throw new Error(MULTISIG_MERGE_WRONG_PREIMAGE_ERROR_MSG)\n }\n const preimg: MultisigMetadataWithPublicKeys = {\n version: unisig.msig.version,\n threshold: unisig.msig.threshold,\n publicKeys: unisig.msig.subsignatures.map((subsig) => subsig.publicKey),\n }\n const msgigAddr = addressFromMultisigPreImg(preimg)\n if (refMsigAddr.toString() !== msgigAddr.toString()) {\n throw new Error(MULTISIG_MERGE_WRONG_PREIMAGE_ERROR_MSG)\n }\n\n // now, we can merge\n unisig.msig.subsignatures.forEach((uniSubsig, index) => {\n if (!uniSubsig.signature) return\n const current = newSubsigs[index]\n if (current.signature && !arrayEqual(uniSubsig.signature, current.signature)) {\n // mismatch\n throw new Error(MULTISIG_MERGE_SIG_MISMATCH_ERROR_MSG)\n }\n current.signature = uniSubsig.signature\n })\n }\n\n const msig: MultisigSignature = {\n version: refSigTx.msig.version,\n threshold: refSigTx.msig.threshold,\n subsignatures: newSubsigs,\n }\n\n const signedTxn: SignedTransaction = {\n txn: refSigTx.txn,\n msig: msig,\n authAddress: refAuthAddr,\n }\n\n return encodeSignedTransaction(signedTxn)\n}\n\n/**\n * Partially signs this transaction with an external raw multisig signature and returns\n * a partially-signed multisig transaction, encoded with msgpack as a typed array.\n * @param transaction - The transaction to sign\n * @param metadata - multisig metadata\n * @param signerAddr - address of the signer\n * @param signature - raw multisig signature\n * @returns an encoded, partially signed multisig transaction.\n */\nfunction partialSignWithMultisigSignature(\n transaction: Transaction,\n metadata: MultisigMetadataWithPublicKeys,\n signerAddr: string | Address,\n signature: Uint8Array,\n) {\n if (signature.length != SIGNATURE_BYTE_LENGTH) {\n throw new Error(MULTISIG_SIGNATURE_LENGTH_ERROR_MSG)\n }\n const signerAddressObj = typeof signerAddr === 'string' ? Address.fromString(signerAddr) : signerAddr\n return createMultisigTransactionWithSignature(\n transaction,\n {\n rawSig: signature,\n myPk: signerAddressObj.publicKey,\n },\n metadata,\n )\n}\n\n/**\n * Takes a multisig transaction blob, and appends a given raw signature to it.\n * This makes it possible to compile a multisig signature using only raw signatures from external methods.\n * @param multisigTxnBlob - an encoded multisig txn. Supports non-payment txn types.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param addrs - a list of Algorand addresses representing possible signers for this multisig. Order is important.\n * @param signerAddr - address of the signer\n * @param signature - raw multisig signature\n * @returns object containing txID, and blob representing encoded multisig txn\n */\nexport function appendSignRawMultisigSignature(\n multisigTxnBlob: Uint8Array,\n { version, threshold, addrs }: MultisigMetadata,\n signerAddr: string | Address,\n signature: Uint8Array,\n) {\n const publicKeys = toPublicKeys(addrs)\n // obtain underlying txn, sign it, and merge it\n const multisigTxObj = decodeSignedTransaction(multisigTxnBlob)\n const partialSignedBlob = partialSignWithMultisigSignature(multisigTxObj.txn, { version, threshold, publicKeys }, signerAddr, signature)\n return {\n txID: multisigTxObj.txn.txId(),\n blob: mergeMultisigTransactions([multisigTxnBlob, partialSignedBlob]),\n }\n}\n\n/**\n * Takes multisig parameters and returns a 32 byte typed array public key,\n * representing an address that identifies the \"exact group, version, and public keys\" that are required for signing.\n * Hash(\"MultisigAddr\" || version uint8 || threshold uint8 || PK1 || PK2 || ...)\n * Encoding this output yields a human readable address.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param pks - array of typed array public keys\n */\nexport function addressFromMultisigPreImg({\n version,\n threshold,\n publicKeys,\n}: Omit<MultisigMetadata, 'addrs'> & {\n publicKeys: Uint8Array[]\n}): Address {\n if (version > 255 || version < 0) {\n // ^ a tad redundant, but in case in the future version != 1, still check for uint8\n throw new Error(`${INVALID_MSIG_VERSION_ERROR_MSG}: ${version}`)\n }\n if (threshold === 0 || publicKeys.length === 0 || threshold > publicKeys.length || threshold > 255) {\n throw new Error(INVALID_MSIG_THRESHOLD_ERROR_MSG)\n }\n const pkLen = ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH\n if (pkLen !== PUBLIC_KEY_BYTE_LENGTH) {\n throw new Error(UNEXPECTED_PK_LEN_ERROR_MSG)\n }\n const merged = new Uint8Array(MULTISIG_PREIMG2ADDR_PREFIX.length + 2 + pkLen * publicKeys.length)\n merged.set(MULTISIG_PREIMG2ADDR_PREFIX, 0)\n merged.set([version], MULTISIG_PREIMG2ADDR_PREFIX.length)\n merged.set([threshold], MULTISIG_PREIMG2ADDR_PREFIX.length + 1)\n for (let i = 0; i < publicKeys.length; i++) {\n if (publicKeys[i].length !== pkLen) {\n throw new Error(INVALID_MSIG_PK_ERROR_MSG)\n }\n merged.set(publicKeys[i], MULTISIG_PREIMG2ADDR_PREFIX.length + 2 + i * pkLen)\n }\n return new Address(Uint8Array.from(hash(merged)))\n}\n\n/**\n * Takes multisig parameters and returns a human readable Algorand address.\n * This is equivalent to fromMultisigPreImg, but interfaces with encoded addresses.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param addrs - array of encoded addresses\n */\nexport function addressFromMultisigPreImgAddrs({ version, threshold, addrs }: MultisigMetadata): Address {\n return addressFromMultisigPreImg({\n version,\n threshold,\n publicKeys: toPublicKeys(addrs),\n })\n}\n\n/**\n * Takes multisig metadata (preimage) and returns the corresponding human readable Algorand address.\n * @param version - multisig version\n * @param threshold - multisig threshold\n * @param addrs - list of Algorand addresses\n */\nexport const multisigAddress: typeof addressFromMultisigPreImgAddrs = addressFromMultisigPreImgAddrs\n\nexport interface MultisigMetadata {\n /**\n * Multisig version\n */\n version: number\n\n /**\n * Multisig threshold value. Authorization requires a subset of signatures,\n * equal to or greater than the threshold value.\n */\n threshold: number\n\n /**\n * A list of Algorand addresses representing possible signers for this multisig. Order is important.\n */\n addrs: Array<Address>\n}\n\n/** Account wrapper that supports partial or full multisig signing. */\nexport class MultisigAccount implements AddressWithTransactionSigner {\n _params: MultisigMetadata\n _subSigners: (AddressWithTransactionSigner & AddressWithDelegatedLsigSigner)[]\n _addr: Address\n _signer: TransactionSigner\n\n /** The parameters for the multisig account */\n get params(): Readonly<MultisigMetadata> {\n return this._params\n }\n\n /** The list of accounts that are present to sign transactions or lsigs */\n get subSigners() {\n return this._subSigners\n }\n\n /** The address of the multisig account */\n get addr(): Readonly<Address> {\n return this._addr\n }\n\n /** The transaction signer for the multisig account */\n get signer(): TransactionSigner {\n return this._signer\n }\n\n constructor(multisigParams: MultisigMetadata, subSigners: (AddressWithTransactionSigner & AddressWithDelegatedLsigSigner)[]) {\n this._params = multisigParams\n this._subSigners = subSigners\n this._addr = multisigAddress(multisigParams)\n this._signer = async (txns: Transaction[], indexesToSign: number[]): Promise<Uint8Array[]> => {\n const txnsToSign = txns.filter((_, index) => indexesToSign.includes(index))\n const signedMsigTxns: Uint8Array[] = []\n\n for (const txn of txnsToSign) {\n let signedMsigTxn = createMultisigTransaction(txn, this._params)\n\n for (const subSigner of this.subSigners) {\n const stxn = (await subSigner.signer([txn], [0]))[0]\n const sig = decodeSignedTransaction(stxn).sig\n\n if (!sig) {\n throw new Error(\n `Signer for address ${subSigner.addr.toString()} did not produce a valid signature when signing ${txn.txId()} for multisig account ${this._addr.toString()}`,\n )\n }\n\n signedMsigTxn = appendSignRawMultisigSignature(signedMsigTxn, this._params, subSigner.addr, sig).blob\n }\n\n signedMsigTxns.push(signedMsigTxn)\n }\n\n return signedMsigTxns\n }\n }\n}\n/**\n * Decodes MsgPack bytes into a multi signature.\n *\n * @param encodedMultiSignature - The MsgPack encoded multi signature\n * @returns The decoded MultisigSignature or an error if decoding fails.\n */\nexport function decodeMultiSignature(encodedMultiSignature: Uint8Array): MultisigSignature {\n const decodedData = decodeMsgpack(encodedMultiSignature)\n return multiSignatureCodec.decode(decodedData, 'msgpack')\n}\n"],"mappings":"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"}
|
|
@@ -88,7 +88,7 @@ type AppCallTransactionFields = {
|
|
|
88
88
|
/**
|
|
89
89
|
* Resources accessed by the application
|
|
90
90
|
*/
|
|
91
|
-
accessReferences?:
|
|
91
|
+
accessReferences?: ResourceReference[];
|
|
92
92
|
/**
|
|
93
93
|
* The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed.
|
|
94
94
|
*/
|
|
@@ -169,7 +169,7 @@ type BoxReference = {
|
|
|
169
169
|
/**
|
|
170
170
|
* Names a single resource reference. Only one of the fields should be set.
|
|
171
171
|
*/
|
|
172
|
-
|
|
172
|
+
type ResourceReference = {
|
|
173
173
|
/** Any account addresses whose balance record is accessible by the executing ApprovalProgram or ClearStateProgram. */
|
|
174
174
|
address?: Address;
|
|
175
175
|
/** Application ID whose GlobalState may be read by the executing ApprovalProgram or ClearStateProgram. */
|
|
@@ -182,28 +182,28 @@ interface AccessReference {
|
|
|
182
182
|
locals?: LocalsReference;
|
|
183
183
|
/** Defines a box by its name and the application ID it belongs to. */
|
|
184
184
|
box?: BoxReference;
|
|
185
|
-
}
|
|
185
|
+
};
|
|
186
186
|
/**
|
|
187
187
|
* A grouping of the asset index and address of the account
|
|
188
188
|
*/
|
|
189
|
-
|
|
189
|
+
type HoldingReference = {
|
|
190
190
|
/** The asset index of the holding */
|
|
191
191
|
assetId: bigint;
|
|
192
192
|
/** The address of the account holding the asset */
|
|
193
193
|
address: Address;
|
|
194
|
-
}
|
|
194
|
+
};
|
|
195
195
|
/** A grouping of the application index and address of the account
|
|
196
196
|
*/
|
|
197
|
-
|
|
197
|
+
type LocalsReference = {
|
|
198
198
|
/** The application index of the local state */
|
|
199
199
|
appId: bigint;
|
|
200
200
|
/** The address of the account holding the local state */
|
|
201
201
|
address: Address;
|
|
202
|
-
}
|
|
202
|
+
};
|
|
203
203
|
/**
|
|
204
204
|
* Validate app call transaction fields
|
|
205
205
|
*/
|
|
206
206
|
declare function validateAppCallTransaction(appCall: AppCallTransactionFields): TransactionValidationError[];
|
|
207
207
|
//#endregion
|
|
208
|
-
export {
|
|
208
|
+
export { AppCallTransactionFields, BoxReference, HoldingReference, LocalsReference, OnApplicationComplete, ResourceReference, StateSchema, validateAppCallTransaction };
|
|
209
209
|
//# sourceMappingURL=app-call.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-call.js","names":["TransactionValidationErrorType","MAX_EXTRA_PROGRAM_PAGES","PROGRAM_PAGE_SIZE","MAX_GLOBAL_STATE_KEYS","MAX_LOCAL_STATE_KEYS","MAX_APP_ARGS","MAX_ARGS_SIZE","MAX_ACCOUNT_REFERENCES","MAX_APP_REFERENCES","MAX_ASSET_REFERENCES","MAX_BOX_REFERENCES","MAX_OVERALL_REFERENCES"],"sources":["../../../../../packages/transact/src/transactions/app-call.ts"],"sourcesContent":["import {\n MAX_ACCOUNT_REFERENCES,\n MAX_APP_ARGS,\n MAX_APP_REFERENCES,\n MAX_ARGS_SIZE,\n MAX_ASSET_REFERENCES,\n MAX_BOX_REFERENCES,\n MAX_EXTRA_PROGRAM_PAGES,\n MAX_GLOBAL_STATE_KEYS,\n MAX_LOCAL_STATE_KEYS,\n MAX_OVERALL_REFERENCES,\n PROGRAM_PAGE_SIZE,\n Address,\n} from '@algorandfoundation/algokit-common'\nimport { TransactionValidationError, TransactionValidationErrorType } from './common'\n\n/**\n * Represents an app call transaction that interacts with Algorand Smart Contracts.\n *\n * App call transactions are used to create, update, delete, opt-in to,\n * close out of, or clear state from Algorand apps (smart contracts).\n */\nexport type AppCallTransactionFields = {\n /**\n * ID of the app being called.\n *\n * Set this to 0 to indicate an app creation call.\n */\n appId: bigint\n\n /**\n * Defines what additional actions occur with the transaction.\n */\n onComplete: OnApplicationComplete\n\n /**\n * Logic executed for every app call transaction, except when\n * on-completion is set to \"clear\".\n *\n * Approval programs may reject the transaction.\n * Only required for app creation and update transactions.\n */\n approvalProgram?: Uint8Array\n\n /**\n * Logic executed for app call transactions with on-completion set to \"clear\".\n *\n * Clear state programs cannot reject the transaction.\n * Only required for app creation and update transactions.\n */\n clearStateProgram?: Uint8Array\n\n /**\n * Holds the maximum number of global state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n globalStateSchema?: StateSchema\n\n /**\n * Holds the maximum number of local state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n localStateSchema?: StateSchema\n\n /**\n * Number of additional pages allocated to the app's approval\n * and clear state programs.\n *\n * Each extra program page is 2048 bytes. The sum of approval program\n * and clear state program may not exceed 2048*(1+extra_program_pages) bytes.\n * Currently, the maximum value is 3.\n * This cannot be changed after creation.\n */\n extraProgramPages?: number\n\n /**\n * Transaction specific arguments available in the app's\n * approval program and clear state program.\n */\n args?: Uint8Array[]\n\n /**\n * List of accounts in addition to the sender that may be accessed\n * from the app's approval program and clear state program.\n */\n accountReferences?: Address[]\n\n /**\n * List of apps in addition to the current app that may be called\n * from the app's approval program and clear state program.\n */\n appReferences?: bigint[]\n\n /**\n * Lists the assets whose parameters may be accessed by this app's\n * approval program and clear state program.\n *\n * The access is read-only.\n */\n assetReferences?: bigint[]\n\n /**\n * The boxes that should be made available for the runtime of the program.\n */\n boxReferences?: BoxReference[]\n\n /**\n * Resources accessed by the application\n */\n accessReferences?: AccessReference[]\n\n /**\n * The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed.\n */\n rejectVersion?: number\n}\n\n/**\n * On-completion actions for application transactions.\n *\n * These values define what additional actions occur with the transaction.\n */\nexport enum OnApplicationComplete {\n /**\n * NoOp indicates that an app transaction will simply call its\n * approval program without any additional action.\n */\n NoOp,\n /**\n * OptIn indicates that an app transaction will allocate some\n * local state for the app in the sender's account.\n */\n OptIn,\n /**\n * CloseOut indicates that an app transaction will deallocate\n * some local state for the app from the user's account.\n */\n CloseOut,\n /**\n * ClearState is similar to CloseOut, but may never fail. This\n * allows users to reclaim their minimum balance from an app\n * they no longer wish to opt in to.\n */\n ClearState,\n /**\n * UpdateApplication indicates that an app transaction will\n * update the approval program and clear state program for the app.\n */\n UpdateApplication,\n /**\n * DeleteApplication indicates that an app transaction will\n * delete the app parameters for the app from the creator's\n * balance record.\n */\n DeleteApplication,\n}\n\n/**\n * Schema for app state storage.\n *\n * Defines the maximum number of values that may be stored in app\n * key/value storage for both global and local state.\n */\nexport type StateSchema = {\n /**\n * Maximum number of integer values that may be stored.\n */\n numUints: number\n\n /**\n * Maximum number of byte slice values that may be stored.\n */\n numByteSlices: number\n}\n\n/**\n * Box reference for app call transactions.\n *\n * References a specific box that should be made available for the runtime\n * of the program.\n */\nexport type BoxReference = {\n /**\n * App ID that owns the box.\n * A value of 0 indicates the current app.\n */\n appId: bigint\n\n /**\n * Name of the box.\n */\n name: Uint8Array\n}\n\n/**\n * Names a single resource reference. Only one of the fields should be set.\n */\nexport interface AccessReference {\n /** Any account addresses whose balance record is accessible by the executing ApprovalProgram or ClearStateProgram. */\n address?: Address\n /** Application ID whose GlobalState may be read by the executing ApprovalProgram or ClearStateProgram. */\n appId?: bigint\n /** Asset ID whose AssetParams may be read by the executing ApprovalProgram or ClearStateProgram. */\n assetId?: bigint\n /** Defines a holding by referring to an Address and Asset it belongs to. */\n holding?: HoldingReference\n /** Defines a local state by referring to an Address and App it belongs to. */\n locals?: LocalsReference\n /** Defines a box by its name and the application ID it belongs to. */\n box?: BoxReference\n}\n\n/**\n * A grouping of the asset index and address of the account\n */\nexport interface HoldingReference {\n /** The asset index of the holding */\n assetId: bigint\n\n /** The address of the account holding the asset */\n address: Address\n}\n\n/** A grouping of the application index and address of the account\n */\nexport interface LocalsReference {\n /** The application index of the local state */\n appId: bigint\n\n /** The address of the account holding the local state */\n address: Address\n}\n\nconst FIELD_ARGS = 'Args'\nconst FIELD_APPROVAL_PROGRAM = 'Approval program'\nconst FIELD_CLEAR_STATE_PROGRAM = 'Clear state program'\nconst FIELD_GLOBAL_STATE_SCHEMA = 'Global state schema'\nconst FIELD_LOCAL_STATE_SCHEMA = 'Local state schema'\nconst FIELD_EXTRA_PROGRAM_PAGES = 'Extra program pages'\n\n/**\n * Validate app call transaction fields\n */\nexport function validateAppCallTransaction(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.appId === 0n) {\n // App creation\n errors.push(...validateAppCreation(appCall))\n } else {\n // App call, update, or delete\n errors.push(...validateAppOperation(appCall))\n }\n\n // Common validations for all app operations\n errors.push(...validateAppCommonFields(appCall))\n\n return errors\n}\n\n/**\n * Validate app creation fields\n */\nfunction validateAppCreation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n\n const extraPages = appCall.extraProgramPages ?? 0\n if (extraPages > MAX_EXTRA_PROGRAM_PAGES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_EXTRA_PROGRAM_PAGES,\n actual: extraPages,\n max: MAX_EXTRA_PROGRAM_PAGES,\n unit: 'pages',\n },\n })\n }\n\n const maxProgramSize = PROGRAM_PAGE_SIZE + extraPages * PROGRAM_PAGE_SIZE\n\n if (appCall.approvalProgram && appCall.approvalProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_APPROVAL_PROGRAM,\n actual: appCall.approvalProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.clearStateProgram && appCall.clearStateProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_CLEAR_STATE_PROGRAM,\n actual: appCall.clearStateProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n const totalProgramSize = (appCall.approvalProgram?.length ?? 0) + (appCall.clearStateProgram?.length ?? 0)\n if (totalProgramSize > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Combined approval and clear state programs',\n actual: totalProgramSize,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.globalStateSchema) {\n const totalKeys = appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices\n if (totalKeys > MAX_GLOBAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_GLOBAL_STATE_SCHEMA,\n actual: appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices,\n max: MAX_GLOBAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n if (appCall.localStateSchema) {\n const totalKeys = appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices\n if (totalKeys > MAX_LOCAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_LOCAL_STATE_SCHEMA,\n actual: appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices,\n max: MAX_LOCAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n return errors\n}\n\n/**\n * Validate app operation (update, delete, call) fields\n */\nfunction validateAppOperation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.onComplete === OnApplicationComplete.UpdateApplication) {\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n }\n\n // These fields are immutable and cannot be set for existing apps\n if (appCall.globalStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_GLOBAL_STATE_SCHEMA,\n })\n }\n if (appCall.localStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_LOCAL_STATE_SCHEMA,\n })\n }\n if (appCall.extraProgramPages !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_EXTRA_PROGRAM_PAGES,\n })\n }\n\n return errors\n}\n\n/**\n * Validate common app call fields\n */\nfunction validateAppCommonFields(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.args) {\n if (appCall.args.length > MAX_APP_ARGS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_ARGS,\n actual: appCall.args.length,\n max: MAX_APP_ARGS,\n unit: 'arguments',\n },\n })\n }\n\n const totalArgsSize = appCall.args.reduce((sum, arg) => sum + arg.length, 0)\n if (totalArgsSize > MAX_ARGS_SIZE) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Args total size',\n actual: totalArgsSize,\n max: MAX_ARGS_SIZE,\n unit: 'bytes',\n },\n })\n }\n }\n\n if (appCall.accountReferences && appCall.accountReferences.length > MAX_ACCOUNT_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Account references',\n actual: appCall.accountReferences.length,\n max: MAX_ACCOUNT_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.appReferences && appCall.appReferences.length > MAX_APP_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'App references',\n actual: appCall.appReferences.length,\n max: MAX_APP_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.assetReferences && appCall.assetReferences.length > MAX_ASSET_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Asset references',\n actual: appCall.assetReferences.length,\n max: MAX_ASSET_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate box references\n if (appCall.boxReferences) {\n if (appCall.boxReferences.length > MAX_BOX_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Box references',\n actual: appCall.boxReferences.length,\n max: MAX_BOX_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate that box reference app IDs are in app references\n const appRefs = appCall.appReferences || []\n for (const boxRef of appCall.boxReferences) {\n if (boxRef.appId !== 0n && boxRef.appId !== appCall.appId && !appRefs.includes(boxRef.appId)) {\n errors.push({\n type: TransactionValidationErrorType.ArbitraryConstraint,\n data: `Box reference for app ID ${boxRef.appId} must be in app references`,\n })\n }\n }\n }\n\n // Validate overall reference count\n const totalReferences =\n (appCall.accountReferences?.length || 0) +\n (appCall.appReferences?.length || 0) +\n (appCall.assetReferences?.length || 0) +\n (appCall.boxReferences?.length || 0)\n\n if (totalReferences > MAX_OVERALL_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Total references',\n actual: totalReferences,\n max: MAX_OVERALL_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n return errors\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-call.js","names":["TransactionValidationErrorType","MAX_EXTRA_PROGRAM_PAGES","PROGRAM_PAGE_SIZE","MAX_GLOBAL_STATE_KEYS","MAX_LOCAL_STATE_KEYS","MAX_APP_ARGS","MAX_ARGS_SIZE","MAX_ACCOUNT_REFERENCES","MAX_APP_REFERENCES","MAX_ASSET_REFERENCES","MAX_BOX_REFERENCES","MAX_OVERALL_REFERENCES"],"sources":["../../../../../packages/transact/src/transactions/app-call.ts"],"sourcesContent":["import {\n Address,\n MAX_ACCOUNT_REFERENCES,\n MAX_APP_ARGS,\n MAX_APP_REFERENCES,\n MAX_ARGS_SIZE,\n MAX_ASSET_REFERENCES,\n MAX_BOX_REFERENCES,\n MAX_EXTRA_PROGRAM_PAGES,\n MAX_GLOBAL_STATE_KEYS,\n MAX_LOCAL_STATE_KEYS,\n MAX_OVERALL_REFERENCES,\n PROGRAM_PAGE_SIZE,\n} from '@algorandfoundation/algokit-common'\nimport { TransactionValidationError, TransactionValidationErrorType } from './common'\n\n/**\n * Represents an app call transaction that interacts with Algorand Smart Contracts.\n *\n * App call transactions are used to create, update, delete, opt-in to,\n * close out of, or clear state from Algorand apps (smart contracts).\n */\nexport type AppCallTransactionFields = {\n /**\n * ID of the app being called.\n *\n * Set this to 0 to indicate an app creation call.\n */\n appId: bigint\n\n /**\n * Defines what additional actions occur with the transaction.\n */\n onComplete: OnApplicationComplete\n\n /**\n * Logic executed for every app call transaction, except when\n * on-completion is set to \"clear\".\n *\n * Approval programs may reject the transaction.\n * Only required for app creation and update transactions.\n */\n approvalProgram?: Uint8Array\n\n /**\n * Logic executed for app call transactions with on-completion set to \"clear\".\n *\n * Clear state programs cannot reject the transaction.\n * Only required for app creation and update transactions.\n */\n clearStateProgram?: Uint8Array\n\n /**\n * Holds the maximum number of global state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n globalStateSchema?: StateSchema\n\n /**\n * Holds the maximum number of local state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n localStateSchema?: StateSchema\n\n /**\n * Number of additional pages allocated to the app's approval\n * and clear state programs.\n *\n * Each extra program page is 2048 bytes. The sum of approval program\n * and clear state program may not exceed 2048*(1+extra_program_pages) bytes.\n * Currently, the maximum value is 3.\n * This cannot be changed after creation.\n */\n extraProgramPages?: number\n\n /**\n * Transaction specific arguments available in the app's\n * approval program and clear state program.\n */\n args?: Uint8Array[]\n\n /**\n * List of accounts in addition to the sender that may be accessed\n * from the app's approval program and clear state program.\n */\n accountReferences?: Address[]\n\n /**\n * List of apps in addition to the current app that may be called\n * from the app's approval program and clear state program.\n */\n appReferences?: bigint[]\n\n /**\n * Lists the assets whose parameters may be accessed by this app's\n * approval program and clear state program.\n *\n * The access is read-only.\n */\n assetReferences?: bigint[]\n\n /**\n * The boxes that should be made available for the runtime of the program.\n */\n boxReferences?: BoxReference[]\n\n /**\n * Resources accessed by the application\n */\n accessReferences?: ResourceReference[]\n\n /**\n * The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed.\n */\n rejectVersion?: number\n}\n\n/**\n * On-completion actions for application transactions.\n *\n * These values define what additional actions occur with the transaction.\n */\nexport enum OnApplicationComplete {\n /**\n * NoOp indicates that an app transaction will simply call its\n * approval program without any additional action.\n */\n NoOp,\n /**\n * OptIn indicates that an app transaction will allocate some\n * local state for the app in the sender's account.\n */\n OptIn,\n /**\n * CloseOut indicates that an app transaction will deallocate\n * some local state for the app from the user's account.\n */\n CloseOut,\n /**\n * ClearState is similar to CloseOut, but may never fail. This\n * allows users to reclaim their minimum balance from an app\n * they no longer wish to opt in to.\n */\n ClearState,\n /**\n * UpdateApplication indicates that an app transaction will\n * update the approval program and clear state program for the app.\n */\n UpdateApplication,\n /**\n * DeleteApplication indicates that an app transaction will\n * delete the app parameters for the app from the creator's\n * balance record.\n */\n DeleteApplication,\n}\n\n/**\n * Schema for app state storage.\n *\n * Defines the maximum number of values that may be stored in app\n * key/value storage for both global and local state.\n */\nexport type StateSchema = {\n /**\n * Maximum number of integer values that may be stored.\n */\n numUints: number\n\n /**\n * Maximum number of byte slice values that may be stored.\n */\n numByteSlices: number\n}\n\n/**\n * Box reference for app call transactions.\n *\n * References a specific box that should be made available for the runtime\n * of the program.\n */\nexport type BoxReference = {\n /**\n * App ID that owns the box.\n * A value of 0 indicates the current app.\n */\n appId: bigint\n\n /**\n * Name of the box.\n */\n name: Uint8Array\n}\n\n/**\n * Names a single resource reference. Only one of the fields should be set.\n */\nexport type ResourceReference = {\n /** Any account addresses whose balance record is accessible by the executing ApprovalProgram or ClearStateProgram. */\n address?: Address\n /** Application ID whose GlobalState may be read by the executing ApprovalProgram or ClearStateProgram. */\n appId?: bigint\n /** Asset ID whose AssetParams may be read by the executing ApprovalProgram or ClearStateProgram. */\n assetId?: bigint\n /** Defines a holding by referring to an Address and Asset it belongs to. */\n holding?: HoldingReference\n /** Defines a local state by referring to an Address and App it belongs to. */\n locals?: LocalsReference\n /** Defines a box by its name and the application ID it belongs to. */\n box?: BoxReference\n}\n\n/**\n * A grouping of the asset index and address of the account\n */\nexport type HoldingReference = {\n /** The asset index of the holding */\n assetId: bigint\n\n /** The address of the account holding the asset */\n address: Address\n}\n\n/** A grouping of the application index and address of the account\n */\nexport type LocalsReference = {\n /** The application index of the local state */\n appId: bigint\n\n /** The address of the account holding the local state */\n address: Address\n}\n\nconst FIELD_ARGS = 'Args'\nconst FIELD_APPROVAL_PROGRAM = 'Approval program'\nconst FIELD_CLEAR_STATE_PROGRAM = 'Clear state program'\nconst FIELD_GLOBAL_STATE_SCHEMA = 'Global state schema'\nconst FIELD_LOCAL_STATE_SCHEMA = 'Local state schema'\nconst FIELD_EXTRA_PROGRAM_PAGES = 'Extra program pages'\n\n/**\n * Validate app call transaction fields\n */\nexport function validateAppCallTransaction(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.appId === 0n) {\n // App creation\n errors.push(...validateAppCreation(appCall))\n } else {\n // App call, update, or delete\n errors.push(...validateAppOperation(appCall))\n }\n\n // Common validations for all app operations\n errors.push(...validateAppCommonFields(appCall))\n\n return errors\n}\n\n/**\n * Validate app creation fields\n */\nfunction validateAppCreation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n\n const extraPages = appCall.extraProgramPages ?? 0\n if (extraPages > MAX_EXTRA_PROGRAM_PAGES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_EXTRA_PROGRAM_PAGES,\n actual: extraPages,\n max: MAX_EXTRA_PROGRAM_PAGES,\n unit: 'pages',\n },\n })\n }\n\n const maxProgramSize = PROGRAM_PAGE_SIZE + extraPages * PROGRAM_PAGE_SIZE\n\n if (appCall.approvalProgram && appCall.approvalProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_APPROVAL_PROGRAM,\n actual: appCall.approvalProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.clearStateProgram && appCall.clearStateProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_CLEAR_STATE_PROGRAM,\n actual: appCall.clearStateProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n const totalProgramSize = (appCall.approvalProgram?.length ?? 0) + (appCall.clearStateProgram?.length ?? 0)\n if (totalProgramSize > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Combined approval and clear state programs',\n actual: totalProgramSize,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.globalStateSchema) {\n const totalKeys = appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices\n if (totalKeys > MAX_GLOBAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_GLOBAL_STATE_SCHEMA,\n actual: appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices,\n max: MAX_GLOBAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n if (appCall.localStateSchema) {\n const totalKeys = appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices\n if (totalKeys > MAX_LOCAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_LOCAL_STATE_SCHEMA,\n actual: appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices,\n max: MAX_LOCAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n return errors\n}\n\n/**\n * Validate app operation (update, delete, call) fields\n */\nfunction validateAppOperation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.onComplete === OnApplicationComplete.UpdateApplication) {\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n }\n\n // These fields are immutable and cannot be set for existing apps\n if (appCall.globalStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_GLOBAL_STATE_SCHEMA,\n })\n }\n if (appCall.localStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_LOCAL_STATE_SCHEMA,\n })\n }\n if (appCall.extraProgramPages !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_EXTRA_PROGRAM_PAGES,\n })\n }\n\n return errors\n}\n\n/**\n * Validate common app call fields\n */\nfunction validateAppCommonFields(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.args) {\n if (appCall.args.length > MAX_APP_ARGS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_ARGS,\n actual: appCall.args.length,\n max: MAX_APP_ARGS,\n unit: 'arguments',\n },\n })\n }\n\n const totalArgsSize = appCall.args.reduce((sum, arg) => sum + arg.length, 0)\n if (totalArgsSize > MAX_ARGS_SIZE) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Args total size',\n actual: totalArgsSize,\n max: MAX_ARGS_SIZE,\n unit: 'bytes',\n },\n })\n }\n }\n\n if (appCall.accountReferences && appCall.accountReferences.length > MAX_ACCOUNT_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Account references',\n actual: appCall.accountReferences.length,\n max: MAX_ACCOUNT_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.appReferences && appCall.appReferences.length > MAX_APP_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'App references',\n actual: appCall.appReferences.length,\n max: MAX_APP_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.assetReferences && appCall.assetReferences.length > MAX_ASSET_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Asset references',\n actual: appCall.assetReferences.length,\n max: MAX_ASSET_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate box references\n if (appCall.boxReferences) {\n if (appCall.boxReferences.length > MAX_BOX_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Box references',\n actual: appCall.boxReferences.length,\n max: MAX_BOX_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate that box reference app IDs are in app references\n const appRefs = appCall.appReferences || []\n for (const boxRef of appCall.boxReferences) {\n if (boxRef.appId !== 0n && boxRef.appId !== appCall.appId && !appRefs.includes(boxRef.appId)) {\n errors.push({\n type: TransactionValidationErrorType.ArbitraryConstraint,\n data: `Box reference for app ID ${boxRef.appId} must be in app references`,\n })\n }\n }\n }\n\n // Validate overall reference count\n const totalReferences =\n (appCall.accountReferences?.length || 0) +\n (appCall.appReferences?.length || 0) +\n (appCall.assetReferences?.length || 0) +\n (appCall.boxReferences?.length || 0)\n\n if (totalReferences > MAX_OVERALL_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Total references',\n actual: totalReferences,\n max: MAX_OVERALL_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n return errors\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-call.mjs","names":[],"sources":["../../../../../packages/transact/src/transactions/app-call.ts"],"sourcesContent":["import {\n MAX_ACCOUNT_REFERENCES,\n MAX_APP_ARGS,\n MAX_APP_REFERENCES,\n MAX_ARGS_SIZE,\n MAX_ASSET_REFERENCES,\n MAX_BOX_REFERENCES,\n MAX_EXTRA_PROGRAM_PAGES,\n MAX_GLOBAL_STATE_KEYS,\n MAX_LOCAL_STATE_KEYS,\n MAX_OVERALL_REFERENCES,\n PROGRAM_PAGE_SIZE,\n Address,\n} from '@algorandfoundation/algokit-common'\nimport { TransactionValidationError, TransactionValidationErrorType } from './common'\n\n/**\n * Represents an app call transaction that interacts with Algorand Smart Contracts.\n *\n * App call transactions are used to create, update, delete, opt-in to,\n * close out of, or clear state from Algorand apps (smart contracts).\n */\nexport type AppCallTransactionFields = {\n /**\n * ID of the app being called.\n *\n * Set this to 0 to indicate an app creation call.\n */\n appId: bigint\n\n /**\n * Defines what additional actions occur with the transaction.\n */\n onComplete: OnApplicationComplete\n\n /**\n * Logic executed for every app call transaction, except when\n * on-completion is set to \"clear\".\n *\n * Approval programs may reject the transaction.\n * Only required for app creation and update transactions.\n */\n approvalProgram?: Uint8Array\n\n /**\n * Logic executed for app call transactions with on-completion set to \"clear\".\n *\n * Clear state programs cannot reject the transaction.\n * Only required for app creation and update transactions.\n */\n clearStateProgram?: Uint8Array\n\n /**\n * Holds the maximum number of global state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n globalStateSchema?: StateSchema\n\n /**\n * Holds the maximum number of local state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n localStateSchema?: StateSchema\n\n /**\n * Number of additional pages allocated to the app's approval\n * and clear state programs.\n *\n * Each extra program page is 2048 bytes. The sum of approval program\n * and clear state program may not exceed 2048*(1+extra_program_pages) bytes.\n * Currently, the maximum value is 3.\n * This cannot be changed after creation.\n */\n extraProgramPages?: number\n\n /**\n * Transaction specific arguments available in the app's\n * approval program and clear state program.\n */\n args?: Uint8Array[]\n\n /**\n * List of accounts in addition to the sender that may be accessed\n * from the app's approval program and clear state program.\n */\n accountReferences?: Address[]\n\n /**\n * List of apps in addition to the current app that may be called\n * from the app's approval program and clear state program.\n */\n appReferences?: bigint[]\n\n /**\n * Lists the assets whose parameters may be accessed by this app's\n * approval program and clear state program.\n *\n * The access is read-only.\n */\n assetReferences?: bigint[]\n\n /**\n * The boxes that should be made available for the runtime of the program.\n */\n boxReferences?: BoxReference[]\n\n /**\n * Resources accessed by the application\n */\n accessReferences?: AccessReference[]\n\n /**\n * The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed.\n */\n rejectVersion?: number\n}\n\n/**\n * On-completion actions for application transactions.\n *\n * These values define what additional actions occur with the transaction.\n */\nexport enum OnApplicationComplete {\n /**\n * NoOp indicates that an app transaction will simply call its\n * approval program without any additional action.\n */\n NoOp,\n /**\n * OptIn indicates that an app transaction will allocate some\n * local state for the app in the sender's account.\n */\n OptIn,\n /**\n * CloseOut indicates that an app transaction will deallocate\n * some local state for the app from the user's account.\n */\n CloseOut,\n /**\n * ClearState is similar to CloseOut, but may never fail. This\n * allows users to reclaim their minimum balance from an app\n * they no longer wish to opt in to.\n */\n ClearState,\n /**\n * UpdateApplication indicates that an app transaction will\n * update the approval program and clear state program for the app.\n */\n UpdateApplication,\n /**\n * DeleteApplication indicates that an app transaction will\n * delete the app parameters for the app from the creator's\n * balance record.\n */\n DeleteApplication,\n}\n\n/**\n * Schema for app state storage.\n *\n * Defines the maximum number of values that may be stored in app\n * key/value storage for both global and local state.\n */\nexport type StateSchema = {\n /**\n * Maximum number of integer values that may be stored.\n */\n numUints: number\n\n /**\n * Maximum number of byte slice values that may be stored.\n */\n numByteSlices: number\n}\n\n/**\n * Box reference for app call transactions.\n *\n * References a specific box that should be made available for the runtime\n * of the program.\n */\nexport type BoxReference = {\n /**\n * App ID that owns the box.\n * A value of 0 indicates the current app.\n */\n appId: bigint\n\n /**\n * Name of the box.\n */\n name: Uint8Array\n}\n\n/**\n * Names a single resource reference. Only one of the fields should be set.\n */\nexport interface AccessReference {\n /** Any account addresses whose balance record is accessible by the executing ApprovalProgram or ClearStateProgram. */\n address?: Address\n /** Application ID whose GlobalState may be read by the executing ApprovalProgram or ClearStateProgram. */\n appId?: bigint\n /** Asset ID whose AssetParams may be read by the executing ApprovalProgram or ClearStateProgram. */\n assetId?: bigint\n /** Defines a holding by referring to an Address and Asset it belongs to. */\n holding?: HoldingReference\n /** Defines a local state by referring to an Address and App it belongs to. */\n locals?: LocalsReference\n /** Defines a box by its name and the application ID it belongs to. */\n box?: BoxReference\n}\n\n/**\n * A grouping of the asset index and address of the account\n */\nexport interface HoldingReference {\n /** The asset index of the holding */\n assetId: bigint\n\n /** The address of the account holding the asset */\n address: Address\n}\n\n/** A grouping of the application index and address of the account\n */\nexport interface LocalsReference {\n /** The application index of the local state */\n appId: bigint\n\n /** The address of the account holding the local state */\n address: Address\n}\n\nconst FIELD_ARGS = 'Args'\nconst FIELD_APPROVAL_PROGRAM = 'Approval program'\nconst FIELD_CLEAR_STATE_PROGRAM = 'Clear state program'\nconst FIELD_GLOBAL_STATE_SCHEMA = 'Global state schema'\nconst FIELD_LOCAL_STATE_SCHEMA = 'Local state schema'\nconst FIELD_EXTRA_PROGRAM_PAGES = 'Extra program pages'\n\n/**\n * Validate app call transaction fields\n */\nexport function validateAppCallTransaction(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.appId === 0n) {\n // App creation\n errors.push(...validateAppCreation(appCall))\n } else {\n // App call, update, or delete\n errors.push(...validateAppOperation(appCall))\n }\n\n // Common validations for all app operations\n errors.push(...validateAppCommonFields(appCall))\n\n return errors\n}\n\n/**\n * Validate app creation fields\n */\nfunction validateAppCreation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n\n const extraPages = appCall.extraProgramPages ?? 0\n if (extraPages > MAX_EXTRA_PROGRAM_PAGES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_EXTRA_PROGRAM_PAGES,\n actual: extraPages,\n max: MAX_EXTRA_PROGRAM_PAGES,\n unit: 'pages',\n },\n })\n }\n\n const maxProgramSize = PROGRAM_PAGE_SIZE + extraPages * PROGRAM_PAGE_SIZE\n\n if (appCall.approvalProgram && appCall.approvalProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_APPROVAL_PROGRAM,\n actual: appCall.approvalProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.clearStateProgram && appCall.clearStateProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_CLEAR_STATE_PROGRAM,\n actual: appCall.clearStateProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n const totalProgramSize = (appCall.approvalProgram?.length ?? 0) + (appCall.clearStateProgram?.length ?? 0)\n if (totalProgramSize > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Combined approval and clear state programs',\n actual: totalProgramSize,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.globalStateSchema) {\n const totalKeys = appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices\n if (totalKeys > MAX_GLOBAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_GLOBAL_STATE_SCHEMA,\n actual: appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices,\n max: MAX_GLOBAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n if (appCall.localStateSchema) {\n const totalKeys = appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices\n if (totalKeys > MAX_LOCAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_LOCAL_STATE_SCHEMA,\n actual: appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices,\n max: MAX_LOCAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n return errors\n}\n\n/**\n * Validate app operation (update, delete, call) fields\n */\nfunction validateAppOperation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.onComplete === OnApplicationComplete.UpdateApplication) {\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n }\n\n // These fields are immutable and cannot be set for existing apps\n if (appCall.globalStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_GLOBAL_STATE_SCHEMA,\n })\n }\n if (appCall.localStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_LOCAL_STATE_SCHEMA,\n })\n }\n if (appCall.extraProgramPages !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_EXTRA_PROGRAM_PAGES,\n })\n }\n\n return errors\n}\n\n/**\n * Validate common app call fields\n */\nfunction validateAppCommonFields(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.args) {\n if (appCall.args.length > MAX_APP_ARGS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_ARGS,\n actual: appCall.args.length,\n max: MAX_APP_ARGS,\n unit: 'arguments',\n },\n })\n }\n\n const totalArgsSize = appCall.args.reduce((sum, arg) => sum + arg.length, 0)\n if (totalArgsSize > MAX_ARGS_SIZE) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Args total size',\n actual: totalArgsSize,\n max: MAX_ARGS_SIZE,\n unit: 'bytes',\n },\n })\n }\n }\n\n if (appCall.accountReferences && appCall.accountReferences.length > MAX_ACCOUNT_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Account references',\n actual: appCall.accountReferences.length,\n max: MAX_ACCOUNT_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.appReferences && appCall.appReferences.length > MAX_APP_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'App references',\n actual: appCall.appReferences.length,\n max: MAX_APP_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.assetReferences && appCall.assetReferences.length > MAX_ASSET_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Asset references',\n actual: appCall.assetReferences.length,\n max: MAX_ASSET_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate box references\n if (appCall.boxReferences) {\n if (appCall.boxReferences.length > MAX_BOX_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Box references',\n actual: appCall.boxReferences.length,\n max: MAX_BOX_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate that box reference app IDs are in app references\n const appRefs = appCall.appReferences || []\n for (const boxRef of appCall.boxReferences) {\n if (boxRef.appId !== 0n && boxRef.appId !== appCall.appId && !appRefs.includes(boxRef.appId)) {\n errors.push({\n type: TransactionValidationErrorType.ArbitraryConstraint,\n data: `Box reference for app ID ${boxRef.appId} must be in app references`,\n })\n }\n }\n }\n\n // Validate overall reference count\n const totalReferences =\n (appCall.accountReferences?.length || 0) +\n (appCall.appReferences?.length || 0) +\n (appCall.assetReferences?.length || 0) +\n (appCall.boxReferences?.length || 0)\n\n if (totalReferences > MAX_OVERALL_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Total references',\n actual: totalReferences,\n max: MAX_OVERALL_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n return errors\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app-call.mjs","names":[],"sources":["../../../../../packages/transact/src/transactions/app-call.ts"],"sourcesContent":["import {\n Address,\n MAX_ACCOUNT_REFERENCES,\n MAX_APP_ARGS,\n MAX_APP_REFERENCES,\n MAX_ARGS_SIZE,\n MAX_ASSET_REFERENCES,\n MAX_BOX_REFERENCES,\n MAX_EXTRA_PROGRAM_PAGES,\n MAX_GLOBAL_STATE_KEYS,\n MAX_LOCAL_STATE_KEYS,\n MAX_OVERALL_REFERENCES,\n PROGRAM_PAGE_SIZE,\n} from '@algorandfoundation/algokit-common'\nimport { TransactionValidationError, TransactionValidationErrorType } from './common'\n\n/**\n * Represents an app call transaction that interacts with Algorand Smart Contracts.\n *\n * App call transactions are used to create, update, delete, opt-in to,\n * close out of, or clear state from Algorand apps (smart contracts).\n */\nexport type AppCallTransactionFields = {\n /**\n * ID of the app being called.\n *\n * Set this to 0 to indicate an app creation call.\n */\n appId: bigint\n\n /**\n * Defines what additional actions occur with the transaction.\n */\n onComplete: OnApplicationComplete\n\n /**\n * Logic executed for every app call transaction, except when\n * on-completion is set to \"clear\".\n *\n * Approval programs may reject the transaction.\n * Only required for app creation and update transactions.\n */\n approvalProgram?: Uint8Array\n\n /**\n * Logic executed for app call transactions with on-completion set to \"clear\".\n *\n * Clear state programs cannot reject the transaction.\n * Only required for app creation and update transactions.\n */\n clearStateProgram?: Uint8Array\n\n /**\n * Holds the maximum number of global state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n globalStateSchema?: StateSchema\n\n /**\n * Holds the maximum number of local state values.\n *\n * Only required for app creation transactions.\n * This cannot be changed after creation.\n */\n localStateSchema?: StateSchema\n\n /**\n * Number of additional pages allocated to the app's approval\n * and clear state programs.\n *\n * Each extra program page is 2048 bytes. The sum of approval program\n * and clear state program may not exceed 2048*(1+extra_program_pages) bytes.\n * Currently, the maximum value is 3.\n * This cannot be changed after creation.\n */\n extraProgramPages?: number\n\n /**\n * Transaction specific arguments available in the app's\n * approval program and clear state program.\n */\n args?: Uint8Array[]\n\n /**\n * List of accounts in addition to the sender that may be accessed\n * from the app's approval program and clear state program.\n */\n accountReferences?: Address[]\n\n /**\n * List of apps in addition to the current app that may be called\n * from the app's approval program and clear state program.\n */\n appReferences?: bigint[]\n\n /**\n * Lists the assets whose parameters may be accessed by this app's\n * approval program and clear state program.\n *\n * The access is read-only.\n */\n assetReferences?: bigint[]\n\n /**\n * The boxes that should be made available for the runtime of the program.\n */\n boxReferences?: BoxReference[]\n\n /**\n * Resources accessed by the application\n */\n accessReferences?: ResourceReference[]\n\n /**\n * The lowest application version for which this transaction should immediately fail. 0 indicates that no version check should be performed.\n */\n rejectVersion?: number\n}\n\n/**\n * On-completion actions for application transactions.\n *\n * These values define what additional actions occur with the transaction.\n */\nexport enum OnApplicationComplete {\n /**\n * NoOp indicates that an app transaction will simply call its\n * approval program without any additional action.\n */\n NoOp,\n /**\n * OptIn indicates that an app transaction will allocate some\n * local state for the app in the sender's account.\n */\n OptIn,\n /**\n * CloseOut indicates that an app transaction will deallocate\n * some local state for the app from the user's account.\n */\n CloseOut,\n /**\n * ClearState is similar to CloseOut, but may never fail. This\n * allows users to reclaim their minimum balance from an app\n * they no longer wish to opt in to.\n */\n ClearState,\n /**\n * UpdateApplication indicates that an app transaction will\n * update the approval program and clear state program for the app.\n */\n UpdateApplication,\n /**\n * DeleteApplication indicates that an app transaction will\n * delete the app parameters for the app from the creator's\n * balance record.\n */\n DeleteApplication,\n}\n\n/**\n * Schema for app state storage.\n *\n * Defines the maximum number of values that may be stored in app\n * key/value storage for both global and local state.\n */\nexport type StateSchema = {\n /**\n * Maximum number of integer values that may be stored.\n */\n numUints: number\n\n /**\n * Maximum number of byte slice values that may be stored.\n */\n numByteSlices: number\n}\n\n/**\n * Box reference for app call transactions.\n *\n * References a specific box that should be made available for the runtime\n * of the program.\n */\nexport type BoxReference = {\n /**\n * App ID that owns the box.\n * A value of 0 indicates the current app.\n */\n appId: bigint\n\n /**\n * Name of the box.\n */\n name: Uint8Array\n}\n\n/**\n * Names a single resource reference. Only one of the fields should be set.\n */\nexport type ResourceReference = {\n /** Any account addresses whose balance record is accessible by the executing ApprovalProgram or ClearStateProgram. */\n address?: Address\n /** Application ID whose GlobalState may be read by the executing ApprovalProgram or ClearStateProgram. */\n appId?: bigint\n /** Asset ID whose AssetParams may be read by the executing ApprovalProgram or ClearStateProgram. */\n assetId?: bigint\n /** Defines a holding by referring to an Address and Asset it belongs to. */\n holding?: HoldingReference\n /** Defines a local state by referring to an Address and App it belongs to. */\n locals?: LocalsReference\n /** Defines a box by its name and the application ID it belongs to. */\n box?: BoxReference\n}\n\n/**\n * A grouping of the asset index and address of the account\n */\nexport type HoldingReference = {\n /** The asset index of the holding */\n assetId: bigint\n\n /** The address of the account holding the asset */\n address: Address\n}\n\n/** A grouping of the application index and address of the account\n */\nexport type LocalsReference = {\n /** The application index of the local state */\n appId: bigint\n\n /** The address of the account holding the local state */\n address: Address\n}\n\nconst FIELD_ARGS = 'Args'\nconst FIELD_APPROVAL_PROGRAM = 'Approval program'\nconst FIELD_CLEAR_STATE_PROGRAM = 'Clear state program'\nconst FIELD_GLOBAL_STATE_SCHEMA = 'Global state schema'\nconst FIELD_LOCAL_STATE_SCHEMA = 'Local state schema'\nconst FIELD_EXTRA_PROGRAM_PAGES = 'Extra program pages'\n\n/**\n * Validate app call transaction fields\n */\nexport function validateAppCallTransaction(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.appId === 0n) {\n // App creation\n errors.push(...validateAppCreation(appCall))\n } else {\n // App call, update, or delete\n errors.push(...validateAppOperation(appCall))\n }\n\n // Common validations for all app operations\n errors.push(...validateAppCommonFields(appCall))\n\n return errors\n}\n\n/**\n * Validate app creation fields\n */\nfunction validateAppCreation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n\n const extraPages = appCall.extraProgramPages ?? 0\n if (extraPages > MAX_EXTRA_PROGRAM_PAGES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_EXTRA_PROGRAM_PAGES,\n actual: extraPages,\n max: MAX_EXTRA_PROGRAM_PAGES,\n unit: 'pages',\n },\n })\n }\n\n const maxProgramSize = PROGRAM_PAGE_SIZE + extraPages * PROGRAM_PAGE_SIZE\n\n if (appCall.approvalProgram && appCall.approvalProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_APPROVAL_PROGRAM,\n actual: appCall.approvalProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.clearStateProgram && appCall.clearStateProgram.length > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_CLEAR_STATE_PROGRAM,\n actual: appCall.clearStateProgram.length,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n const totalProgramSize = (appCall.approvalProgram?.length ?? 0) + (appCall.clearStateProgram?.length ?? 0)\n if (totalProgramSize > maxProgramSize) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Combined approval and clear state programs',\n actual: totalProgramSize,\n max: maxProgramSize,\n unit: 'bytes',\n },\n })\n }\n\n if (appCall.globalStateSchema) {\n const totalKeys = appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices\n if (totalKeys > MAX_GLOBAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_GLOBAL_STATE_SCHEMA,\n actual: appCall.globalStateSchema.numUints + appCall.globalStateSchema.numByteSlices,\n max: MAX_GLOBAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n if (appCall.localStateSchema) {\n const totalKeys = appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices\n if (totalKeys > MAX_LOCAL_STATE_KEYS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_LOCAL_STATE_SCHEMA,\n actual: appCall.localStateSchema.numUints + appCall.localStateSchema.numByteSlices,\n max: MAX_LOCAL_STATE_KEYS,\n unit: 'keys',\n },\n })\n }\n }\n\n return errors\n}\n\n/**\n * Validate app operation (update, delete, call) fields\n */\nfunction validateAppOperation(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.onComplete === OnApplicationComplete.UpdateApplication) {\n if (!appCall.approvalProgram || appCall.approvalProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_APPROVAL_PROGRAM,\n })\n }\n if (!appCall.clearStateProgram || appCall.clearStateProgram.length === 0) {\n errors.push({\n type: TransactionValidationErrorType.RequiredField,\n data: FIELD_CLEAR_STATE_PROGRAM,\n })\n }\n }\n\n // These fields are immutable and cannot be set for existing apps\n if (appCall.globalStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_GLOBAL_STATE_SCHEMA,\n })\n }\n if (appCall.localStateSchema !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_LOCAL_STATE_SCHEMA,\n })\n }\n if (appCall.extraProgramPages !== undefined) {\n errors.push({\n type: TransactionValidationErrorType.ImmutableField,\n data: FIELD_EXTRA_PROGRAM_PAGES,\n })\n }\n\n return errors\n}\n\n/**\n * Validate common app call fields\n */\nfunction validateAppCommonFields(appCall: AppCallTransactionFields): TransactionValidationError[] {\n const errors = new Array<TransactionValidationError>()\n\n if (appCall.args) {\n if (appCall.args.length > MAX_APP_ARGS) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: FIELD_ARGS,\n actual: appCall.args.length,\n max: MAX_APP_ARGS,\n unit: 'arguments',\n },\n })\n }\n\n const totalArgsSize = appCall.args.reduce((sum, arg) => sum + arg.length, 0)\n if (totalArgsSize > MAX_ARGS_SIZE) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Args total size',\n actual: totalArgsSize,\n max: MAX_ARGS_SIZE,\n unit: 'bytes',\n },\n })\n }\n }\n\n if (appCall.accountReferences && appCall.accountReferences.length > MAX_ACCOUNT_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Account references',\n actual: appCall.accountReferences.length,\n max: MAX_ACCOUNT_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.appReferences && appCall.appReferences.length > MAX_APP_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'App references',\n actual: appCall.appReferences.length,\n max: MAX_APP_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n if (appCall.assetReferences && appCall.assetReferences.length > MAX_ASSET_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Asset references',\n actual: appCall.assetReferences.length,\n max: MAX_ASSET_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate box references\n if (appCall.boxReferences) {\n if (appCall.boxReferences.length > MAX_BOX_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Box references',\n actual: appCall.boxReferences.length,\n max: MAX_BOX_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n // Validate that box reference app IDs are in app references\n const appRefs = appCall.appReferences || []\n for (const boxRef of appCall.boxReferences) {\n if (boxRef.appId !== 0n && boxRef.appId !== appCall.appId && !appRefs.includes(boxRef.appId)) {\n errors.push({\n type: TransactionValidationErrorType.ArbitraryConstraint,\n data: `Box reference for app ID ${boxRef.appId} must be in app references`,\n })\n }\n }\n }\n\n // Validate overall reference count\n const totalReferences =\n (appCall.accountReferences?.length || 0) +\n (appCall.appReferences?.length || 0) +\n (appCall.assetReferences?.length || 0) +\n (appCall.boxReferences?.length || 0)\n\n if (totalReferences > MAX_OVERALL_REFERENCES) {\n errors.push({\n type: TransactionValidationErrorType.FieldTooLong,\n data: {\n field: 'Total references',\n actual: totalReferences,\n max: MAX_OVERALL_REFERENCES,\n unit: 'refs',\n },\n })\n }\n\n return errors\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ObjectModelMetadata } from "../../../common/src/codecs/types.js";
|
|
2
|
+
import { BoxReference, HoldingReference, LocalsReference } from "./app-call.js";
|
|
3
|
+
|
|
4
|
+
//#region packages/transact/src/transactions/reference-types-meta.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Metadata for BoxReference
|
|
8
|
+
*
|
|
9
|
+
* Maps wire format (app, name) to BoxReference (appId, name)
|
|
10
|
+
*/
|
|
11
|
+
declare const BoxReferenceMeta: ObjectModelMetadata<BoxReference>;
|
|
12
|
+
/**
|
|
13
|
+
* Metadata for HoldingReference
|
|
14
|
+
*
|
|
15
|
+
* Maps wire format (account, asset) to HoldingReference (address, assetId)
|
|
16
|
+
*/
|
|
17
|
+
declare const HoldingReferenceMeta: ObjectModelMetadata<HoldingReference>;
|
|
18
|
+
/**
|
|
19
|
+
* Metadata for LocalsReference
|
|
20
|
+
*
|
|
21
|
+
* Maps wire format (account, app) to LocalsReference (address, appId)
|
|
22
|
+
*/
|
|
23
|
+
declare const LocalsReferenceMeta: ObjectModelMetadata<LocalsReference>;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { BoxReferenceMeta, HoldingReferenceMeta, LocalsReferenceMeta };
|
|
26
|
+
//# sourceMappingURL=reference-types-meta.d.ts.map
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const require_address = require('../../../common/src/codecs/primitives/address.js');
|
|
2
|
+
const require_bigint = require('../../../common/src/codecs/primitives/bigint.js');
|
|
3
|
+
const require_bytes = require('../../../common/src/codecs/primitives/bytes.js');
|
|
4
|
+
|
|
5
|
+
//#region packages/transact/src/transactions/reference-types-meta.ts
|
|
6
|
+
/**
|
|
7
|
+
* Metadata for BoxReference
|
|
8
|
+
*
|
|
9
|
+
* Maps wire format (app, name) to BoxReference (appId, name)
|
|
10
|
+
*/
|
|
11
|
+
const BoxReferenceMeta = {
|
|
12
|
+
name: "BoxReference",
|
|
13
|
+
kind: "object",
|
|
14
|
+
fields: [{
|
|
15
|
+
name: "appId",
|
|
16
|
+
wireKey: "app",
|
|
17
|
+
optional: false,
|
|
18
|
+
codec: require_bigint.bigIntCodec
|
|
19
|
+
}, {
|
|
20
|
+
name: "name",
|
|
21
|
+
wireKey: "name",
|
|
22
|
+
optional: false,
|
|
23
|
+
codec: require_bytes.bytesCodec
|
|
24
|
+
}]
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Metadata for HoldingReference
|
|
28
|
+
*
|
|
29
|
+
* Maps wire format (account, asset) to HoldingReference (address, assetId)
|
|
30
|
+
*/
|
|
31
|
+
const HoldingReferenceMeta = {
|
|
32
|
+
name: "HoldingReference",
|
|
33
|
+
kind: "object",
|
|
34
|
+
fields: [{
|
|
35
|
+
name: "address",
|
|
36
|
+
wireKey: "account",
|
|
37
|
+
optional: false,
|
|
38
|
+
codec: require_address.addressCodec
|
|
39
|
+
}, {
|
|
40
|
+
name: "assetId",
|
|
41
|
+
wireKey: "asset",
|
|
42
|
+
optional: false,
|
|
43
|
+
codec: require_bigint.bigIntCodec
|
|
44
|
+
}]
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Metadata for LocalsReference
|
|
48
|
+
*
|
|
49
|
+
* Maps wire format (account, app) to LocalsReference (address, appId)
|
|
50
|
+
*/
|
|
51
|
+
const LocalsReferenceMeta = {
|
|
52
|
+
name: "LocalsReference",
|
|
53
|
+
kind: "object",
|
|
54
|
+
fields: [{
|
|
55
|
+
name: "address",
|
|
56
|
+
wireKey: "account",
|
|
57
|
+
optional: false,
|
|
58
|
+
codec: require_address.addressCodec
|
|
59
|
+
}, {
|
|
60
|
+
name: "appId",
|
|
61
|
+
wireKey: "app",
|
|
62
|
+
optional: false,
|
|
63
|
+
codec: require_bigint.bigIntCodec
|
|
64
|
+
}]
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
exports.BoxReferenceMeta = BoxReferenceMeta;
|
|
69
|
+
exports.HoldingReferenceMeta = HoldingReferenceMeta;
|
|
70
|
+
exports.LocalsReferenceMeta = LocalsReferenceMeta;
|
|
71
|
+
//# sourceMappingURL=reference-types-meta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-types-meta.js","names":["BoxReferenceMeta: ObjectModelMetadata<BoxReference>","bigIntCodec","bytesCodec","HoldingReferenceMeta: ObjectModelMetadata<HoldingReference>","addressCodec","LocalsReferenceMeta: ObjectModelMetadata<LocalsReference>"],"sources":["../../../../../packages/transact/src/transactions/reference-types-meta.ts"],"sourcesContent":["import type { ObjectModelMetadata } from '@algorandfoundation/algokit-common'\nimport { addressCodec, bigIntCodec, bytesCodec } from '@algorandfoundation/algokit-common'\nimport type { BoxReference, HoldingReference, LocalsReference } from './app-call'\n\n/**\n * Metadata for BoxReference\n *\n * Maps wire format (app, name) to BoxReference (appId, name)\n */\nexport const BoxReferenceMeta: ObjectModelMetadata<BoxReference> = {\n name: 'BoxReference',\n kind: 'object',\n fields: [\n { name: 'appId', wireKey: 'app', optional: false, codec: bigIntCodec },\n { name: 'name', wireKey: 'name', optional: false, codec: bytesCodec },\n ],\n}\n\n/**\n * Metadata for HoldingReference\n *\n * Maps wire format (account, asset) to HoldingReference (address, assetId)\n */\nexport const HoldingReferenceMeta: ObjectModelMetadata<HoldingReference> = {\n name: 'HoldingReference',\n kind: 'object',\n fields: [\n { name: 'address', wireKey: 'account', optional: false, codec: addressCodec },\n { name: 'assetId', wireKey: 'asset', optional: false, codec: bigIntCodec },\n ],\n}\n\n/**\n * Metadata for LocalsReference\n *\n * Maps wire format (account, app) to LocalsReference (address, appId)\n */\nexport const LocalsReferenceMeta: ObjectModelMetadata<LocalsReference> = {\n name: 'LocalsReference',\n kind: 'object',\n fields: [\n { name: 'address', wireKey: 'account', optional: false, codec: addressCodec },\n { name: 'appId', wireKey: 'app', optional: false, codec: bigIntCodec },\n ],\n}\n"],"mappings":";;;;;;;;;;AASA,MAAaA,mBAAsD;CACjE,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EAAE,MAAM;EAAS,SAAS;EAAO,UAAU;EAAO,OAAOC;EAAa,EACtE;EAAE,MAAM;EAAQ,SAAS;EAAQ,UAAU;EAAO,OAAOC;EAAY,CACtE;CACF;;;;;;AAOD,MAAaC,uBAA8D;CACzE,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EAAE,MAAM;EAAW,SAAS;EAAW,UAAU;EAAO,OAAOC;EAAc,EAC7E;EAAE,MAAM;EAAW,SAAS;EAAS,UAAU;EAAO,OAAOH;EAAa,CAC3E;CACF;;;;;;AAOD,MAAaI,sBAA4D;CACvE,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EAAE,MAAM;EAAW,SAAS;EAAW,UAAU;EAAO,OAAOD;EAAc,EAC7E;EAAE,MAAM;EAAS,SAAS;EAAO,UAAU;EAAO,OAAOH;EAAa,CACvE;CACF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { addressCodec } from "../../../common/src/codecs/primitives/address.mjs";
|
|
2
|
+
import { bigIntCodec } from "../../../common/src/codecs/primitives/bigint.mjs";
|
|
3
|
+
import { bytesCodec } from "../../../common/src/codecs/primitives/bytes.mjs";
|
|
4
|
+
|
|
5
|
+
//#region packages/transact/src/transactions/reference-types-meta.ts
|
|
6
|
+
/**
|
|
7
|
+
* Metadata for BoxReference
|
|
8
|
+
*
|
|
9
|
+
* Maps wire format (app, name) to BoxReference (appId, name)
|
|
10
|
+
*/
|
|
11
|
+
const BoxReferenceMeta = {
|
|
12
|
+
name: "BoxReference",
|
|
13
|
+
kind: "object",
|
|
14
|
+
fields: [{
|
|
15
|
+
name: "appId",
|
|
16
|
+
wireKey: "app",
|
|
17
|
+
optional: false,
|
|
18
|
+
codec: bigIntCodec
|
|
19
|
+
}, {
|
|
20
|
+
name: "name",
|
|
21
|
+
wireKey: "name",
|
|
22
|
+
optional: false,
|
|
23
|
+
codec: bytesCodec
|
|
24
|
+
}]
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Metadata for HoldingReference
|
|
28
|
+
*
|
|
29
|
+
* Maps wire format (account, asset) to HoldingReference (address, assetId)
|
|
30
|
+
*/
|
|
31
|
+
const HoldingReferenceMeta = {
|
|
32
|
+
name: "HoldingReference",
|
|
33
|
+
kind: "object",
|
|
34
|
+
fields: [{
|
|
35
|
+
name: "address",
|
|
36
|
+
wireKey: "account",
|
|
37
|
+
optional: false,
|
|
38
|
+
codec: addressCodec
|
|
39
|
+
}, {
|
|
40
|
+
name: "assetId",
|
|
41
|
+
wireKey: "asset",
|
|
42
|
+
optional: false,
|
|
43
|
+
codec: bigIntCodec
|
|
44
|
+
}]
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Metadata for LocalsReference
|
|
48
|
+
*
|
|
49
|
+
* Maps wire format (account, app) to LocalsReference (address, appId)
|
|
50
|
+
*/
|
|
51
|
+
const LocalsReferenceMeta = {
|
|
52
|
+
name: "LocalsReference",
|
|
53
|
+
kind: "object",
|
|
54
|
+
fields: [{
|
|
55
|
+
name: "address",
|
|
56
|
+
wireKey: "account",
|
|
57
|
+
optional: false,
|
|
58
|
+
codec: addressCodec
|
|
59
|
+
}, {
|
|
60
|
+
name: "appId",
|
|
61
|
+
wireKey: "app",
|
|
62
|
+
optional: false,
|
|
63
|
+
codec: bigIntCodec
|
|
64
|
+
}]
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
//#endregion
|
|
68
|
+
export { BoxReferenceMeta, HoldingReferenceMeta, LocalsReferenceMeta };
|
|
69
|
+
//# sourceMappingURL=reference-types-meta.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference-types-meta.mjs","names":["BoxReferenceMeta: ObjectModelMetadata<BoxReference>","HoldingReferenceMeta: ObjectModelMetadata<HoldingReference>","LocalsReferenceMeta: ObjectModelMetadata<LocalsReference>"],"sources":["../../../../../packages/transact/src/transactions/reference-types-meta.ts"],"sourcesContent":["import type { ObjectModelMetadata } from '@algorandfoundation/algokit-common'\nimport { addressCodec, bigIntCodec, bytesCodec } from '@algorandfoundation/algokit-common'\nimport type { BoxReference, HoldingReference, LocalsReference } from './app-call'\n\n/**\n * Metadata for BoxReference\n *\n * Maps wire format (app, name) to BoxReference (appId, name)\n */\nexport const BoxReferenceMeta: ObjectModelMetadata<BoxReference> = {\n name: 'BoxReference',\n kind: 'object',\n fields: [\n { name: 'appId', wireKey: 'app', optional: false, codec: bigIntCodec },\n { name: 'name', wireKey: 'name', optional: false, codec: bytesCodec },\n ],\n}\n\n/**\n * Metadata for HoldingReference\n *\n * Maps wire format (account, asset) to HoldingReference (address, assetId)\n */\nexport const HoldingReferenceMeta: ObjectModelMetadata<HoldingReference> = {\n name: 'HoldingReference',\n kind: 'object',\n fields: [\n { name: 'address', wireKey: 'account', optional: false, codec: addressCodec },\n { name: 'assetId', wireKey: 'asset', optional: false, codec: bigIntCodec },\n ],\n}\n\n/**\n * Metadata for LocalsReference\n *\n * Maps wire format (account, app) to LocalsReference (address, appId)\n */\nexport const LocalsReferenceMeta: ObjectModelMetadata<LocalsReference> = {\n name: 'LocalsReference',\n kind: 'object',\n fields: [\n { name: 'address', wireKey: 'account', optional: false, codec: addressCodec },\n { name: 'appId', wireKey: 'app', optional: false, codec: bigIntCodec },\n ],\n}\n"],"mappings":";;;;;;;;;;AASA,MAAaA,mBAAsD;CACjE,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EAAE,MAAM;EAAS,SAAS;EAAO,UAAU;EAAO,OAAO;EAAa,EACtE;EAAE,MAAM;EAAQ,SAAS;EAAQ,UAAU;EAAO,OAAO;EAAY,CACtE;CACF;;;;;;AAOD,MAAaC,uBAA8D;CACzE,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EAAE,MAAM;EAAW,SAAS;EAAW,UAAU;EAAO,OAAO;EAAc,EAC7E;EAAE,MAAM;EAAW,SAAS;EAAS,UAAU;EAAO,OAAO;EAAa,CAC3E;CACF;;;;;;AAOD,MAAaC,sBAA4D;CACvE,MAAM;CACN,MAAM;CACN,QAAQ,CACN;EAAE,MAAM;EAAW,SAAS;EAAW,UAAU;EAAO,OAAO;EAAc,EAC7E;EAAE,MAAM;EAAS,SAAS;EAAO,UAAU;EAAO,OAAO;EAAa,CACvE;CACF"}
|