@algorandfoundation/algokit-utils 10.0.0-alpha.28 → 10.0.0-alpha.29

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/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "**"
7
7
  ],
8
8
  "name": "@algorandfoundation/algokit-utils",
9
- "version": "10.0.0-alpha.28",
9
+ "version": "10.0.0-alpha.29",
10
10
  "private": false,
11
11
  "description": "A set of core Algorand utilities written in TypeScript and released via npm that make it easier to build solutions on Algorand.",
12
12
  "author": "Algorand Foundation",
@@ -40,7 +40,6 @@ declare class Address {
40
40
  * Get the zero address.
41
41
  */
42
42
  static zeroAddress(): Address;
43
- static [Symbol.hasInstance](obj: unknown): boolean;
44
43
  }
45
44
  interface Addressable {
46
45
  addr: Readonly<Address>;
@@ -89,10 +89,11 @@ var Address = class Address {
89
89
  static zeroAddress() {
90
90
  return new Address(new Uint8Array(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH));
91
91
  }
92
- static [Symbol.hasInstance](obj) {
93
- return Boolean(obj && typeof obj === "object" && ADDR_SYMBOL in obj && obj[ADDR_SYMBOL]);
94
- }
95
92
  };
93
+ Object.defineProperty(Address, Symbol.hasInstance, { value: function(obj) {
94
+ if (obj instanceof Object && Object.getPrototypeOf(obj) === Address.prototype) return true;
95
+ return Boolean(obj && typeof obj === "object" && ADDR_SYMBOL in obj && obj[ADDR_SYMBOL]);
96
+ } });
96
97
  function getAddress(addr) {
97
98
  if (typeof addr == "string") return Address.fromString(addr);
98
99
  else if ("addr" in addr) return addr.addr;
@@ -1 +1 @@
1
- {"version":3,"file":"address.js","names":["sha512","HASH_BYTES_LENGTH","CHECKSUM_BYTE_LENGTH","arrayEqual","base32","concatArrays"],"sources":["../../../../packages/common/src/address.ts"],"sourcesContent":["import base32 from 'hi-base32'\nimport sha512 from 'js-sha512'\nimport { arrayEqual, concatArrays } from './array'\nimport { CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH } from './constants'\n\nexport const ALGORAND_ADDRESS_BYTE_LENGTH = 36\nexport const ALGORAND_CHECKSUM_BYTE_LENGTH = 4\nexport const ALGORAND_ADDRESS_LENGTH = 58\nexport const ALGORAND_ZERO_ADDRESS_STRING = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ'\n\nexport const MALFORMED_ADDRESS_ERROR_MSG = 'address seems to be malformed'\nexport const CHECKSUM_ADDRESS_ERROR_MSG = 'wrong checksum for address'\n\nexport function checksumFromPublicKey(publicKey: Uint8Array): Uint8Array {\n return Uint8Array.from(sha512.sha512_256.array(publicKey).slice(HASH_BYTES_LENGTH - CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH))\n}\n\nfunction genericHash(arr: sha512.Message) {\n return sha512.sha512_256.array(arr)\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('hex')\n}\n\nexport function encodeUint64(num: number | bigint) {\n const isInteger = typeof num === 'bigint' || Number.isInteger(num)\n\n if (!isInteger || num < 0 || num > BigInt('0xffffffffffffffff')) {\n throw new Error('Input is not a 64-bit unsigned integer')\n }\n\n const encoding = new Uint8Array(8)\n const view = new DataView(encoding.buffer)\n view.setBigUint64(0, BigInt(num))\n\n return encoding\n}\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nconst ADDR_SYMBOL = Symbol.for('algokit_common:Address')\n\n/**\n * Represents an Algorand address\n */\nexport class Address {\n /**\n * The binary form of the address. For standard accounts, this is the public key.\n */\n public readonly publicKey: Uint8Array;\n\n /** @internal */\n [ADDR_SYMBOL]: boolean\n\n /**\n * Create a new Address object from its binary form.\n * @param publicKey - The binary form of the address. Must be 32 bytes.\n */\n constructor(publicKey: Uint8Array) {\n this[ADDR_SYMBOL] = true\n if (publicKey.length !== ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: 0x${bytesToHex(publicKey)}, length ${publicKey.length}`)\n this.publicKey = publicKey\n }\n\n /**\n * Check if the address is equal to another address.\n */\n equals(other: Address): boolean {\n return other instanceof Address && arrayEqual(this.publicKey, other.publicKey)\n }\n\n /**\n * Compute the 4 byte checksum of the address.\n */\n checksum(): Uint8Array {\n return checksumFromPublicKey(this.publicKey)\n }\n\n /**\n * Encode the address into a string form.\n */\n toString(): string {\n const addr = base32.encode(concatArrays(this.publicKey, this.checksum()))\n return addr.slice(0, ALGORAND_ADDRESS_LENGTH) // removing the extra '===='\n }\n\n /**\n * Decode an address from a string.\n * @param address - The address to decode. Must be 58 characters long.\n * @returns An Address object corresponding to the input string.\n */\n static fromString(address: string): Address {\n if (typeof address !== 'string') throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected string, got ${typeof address}, ${address}`)\n if (address.length !== ALGORAND_ADDRESS_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected length ${ALGORAND_ADDRESS_LENGTH}, got ${address.length}: ${address}`)\n\n // try to decode\n const decoded = base32.decode.asBytes(address)\n // Sanity check\n if (decoded.length !== ALGORAND_ADDRESS_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected byte length ${ALGORAND_ADDRESS_BYTE_LENGTH}, got ${decoded.length}`)\n\n // Find publickey and checksum\n const pk = new Uint8Array(decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n const cs = new Uint8Array(decoded.slice(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, ALGORAND_ADDRESS_BYTE_LENGTH))\n const checksum = checksumFromPublicKey(pk)\n // Check if the checksum and the address are equal\n if (!arrayEqual(checksum, cs)) throw new Error(`${CHECKSUM_ADDRESS_ERROR_MSG}: ${address} (${cs}, ${checksum})`)\n\n return new Address(pk)\n }\n\n /**\n * Get the zero address.\n */\n static zeroAddress(): Address {\n return new Address(new Uint8Array(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n }\n\n static [Symbol.hasInstance](obj: unknown) {\n return Boolean(obj && typeof obj === 'object' && ADDR_SYMBOL in obj && obj[ADDR_SYMBOL as keyof typeof obj])\n }\n}\n\nexport interface Addressable {\n addr: Readonly<Address>\n}\n\nexport type ReadableAddress = Addressable | Address | string\n\nexport function getAddress(addr: ReadableAddress): Address {\n if (typeof addr == 'string') {\n return Address.fromString(addr)\n } else if ('addr' in addr) {\n return addr.addr\n } else {\n return addr\n }\n}\n\nexport function getOptionalAddress(addr: ReadableAddress | undefined): Address | undefined {\n if (addr === undefined) {\n return undefined\n }\n return getAddress(addr)\n}\n\n/**\n * isValidAddress checks if a string is a valid Algorand address.\n * @param address - an Algorand address with checksum.\n * @returns true if valid, false otherwise\n */\nexport function isValidAddress(address: string): boolean {\n // Try to decode\n try {\n Address.fromString(address)\n } catch {\n return false\n }\n return true\n}\n\nconst APP_ID_PREFIX = new TextEncoder().encode('appID')\n\n/**\n * Get the escrow address of an application.\n * @param appID - The ID of the application.\n * @returns The address corresponding to that application's escrow account.\n */\nexport function getApplicationAddress(appID: number | bigint): Address {\n const toBeSigned = concatArrays(APP_ID_PREFIX, encodeUint64(appID))\n const hash = genericHash(toBeSigned)\n return new Address(Uint8Array.from(hash))\n}\n\n/**\n * decodeAddress takes an Algorand address in string form and decodes it into a Uint8Array.\n * @param address - an Algorand address with checksum.\n * @returns the decoded form of the address's public key and checksum\n */\nexport function decodeAddress(address: string): Address {\n return Address.fromString(address)\n}\n\n/**\n * encodeAddress takes an Algorand address as a Uint8Array and encodes it into a string with checksum.\n * @param address - a raw Algorand address\n * @returns the address and checksum encoded as a string.\n */\nexport function encodeAddress(address: Uint8Array): string {\n return new Address(address).toString()\n}\n"],"mappings":";;;;;;;;;AAKA,MAAa,+BAA+B;AAC5C,MAAa,gCAAgC;AAC7C,MAAa,0BAA0B;AACvC,MAAa,+BAA+B;AAE5C,MAAa,8BAA8B;AAC3C,MAAa,6BAA6B;AAE1C,SAAgB,sBAAsB,WAAmC;AACvE,QAAO,WAAW,KAAKA,kBAAO,WAAW,MAAM,UAAU,CAAC,MAAMC,sCAAoBC,wCAAsBD,oCAAkB,CAAC;;AAG/H,SAAS,YAAY,KAAqB;AACxC,QAAOD,kBAAO,WAAW,MAAM,IAAI;;AAGrC,SAAS,WAAW,OAA2B;AAC7C,QAAO,OAAO,KAAK,MAAM,CAAC,SAAS,MAAM;;AAG3C,SAAgB,aAAa,KAAsB;AAGjD,KAAI,EAFc,OAAO,QAAQ,YAAY,OAAO,UAAU,IAAI,KAEhD,MAAM,KAAK,MAAM,OAAO,qBAAqB,CAC7D,OAAM,IAAI,MAAM,yCAAyC;CAG3D,MAAM,WAAW,IAAI,WAAW,EAAE;AAElC,CADa,IAAI,SAAS,SAAS,OAAO,CACrC,aAAa,GAAG,OAAO,IAAI,CAAC;AAEjC,QAAO;;;AAIT,MAAM,cAAc,OAAO,IAAI,yBAAyB;;;;AAKxD,IAAa,UAAb,MAAa,QAAQ;;;;CAInB,AAAgB;;CAGhB,CAAC;;;;;CAMD,YAAY,WAAuB;AACjC,OAAK,eAAe;AACpB,MAAI,UAAU,WAAW,+BAA+B,8BACtD,OAAM,IAAI,MAAM,GAAG,4BAA4B,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,SAAS;AAC3G,OAAK,YAAY;;;;;CAMnB,OAAO,OAAyB;AAC9B,SAAO,iBAAiB,WAAWG,yBAAW,KAAK,WAAW,MAAM,UAAU;;;;;CAMhF,WAAuB;AACrB,SAAO,sBAAsB,KAAK,UAAU;;;;;CAM9C,WAAmB;AAEjB,SADaC,kBAAO,OAAOC,2BAAa,KAAK,WAAW,KAAK,UAAU,CAAC,CAAC,CAC7D,MAAM,GAAG,wBAAwB;;;;;;;CAQ/C,OAAO,WAAW,SAA0B;AAC1C,MAAI,OAAO,YAAY,SAAU,OAAM,IAAI,MAAM,GAAG,4BAA4B,yBAAyB,OAAO,QAAQ,IAAI,UAAU;AACtI,MAAI,QAAQ,WAAW,wBACrB,OAAM,IAAI,MAAM,GAAG,4BAA4B,oBAAoB,wBAAwB,QAAQ,QAAQ,OAAO,IAAI,UAAU;EAGlI,MAAM,UAAUD,kBAAO,OAAO,QAAQ,QAAQ;AAE9C,MAAI,QAAQ,WAAW,6BACrB,OAAM,IAAI,MAAM,GAAG,4BAA4B,yBAAyB,6BAA6B,QAAQ,QAAQ,SAAS;EAGhI,MAAM,KAAK,IAAI,WAAW,QAAQ,MAAM,GAAG,+BAA+B,8BAA8B,CAAC;EACzG,MAAM,KAAK,IAAI,WAAW,QAAQ,MAAM,+BAA+B,+BAA+B,6BAA6B,CAAC;EACpI,MAAM,WAAW,sBAAsB,GAAG;AAE1C,MAAI,CAACD,yBAAW,UAAU,GAAG,CAAE,OAAM,IAAI,MAAM,GAAG,2BAA2B,IAAI,QAAQ,IAAI,GAAG,IAAI,SAAS,GAAG;AAEhH,SAAO,IAAI,QAAQ,GAAG;;;;;CAMxB,OAAO,cAAuB;AAC5B,SAAO,IAAI,QAAQ,IAAI,WAAW,+BAA+B,8BAA8B,CAAC;;CAGlG,QAAQ,OAAO,aAAa,KAAc;AACxC,SAAO,QAAQ,OAAO,OAAO,QAAQ,YAAY,eAAe,OAAO,IAAI,aAAiC;;;AAUhH,SAAgB,WAAW,MAAgC;AACzD,KAAI,OAAO,QAAQ,SACjB,QAAO,QAAQ,WAAW,KAAK;UACtB,UAAU,KACnB,QAAO,KAAK;KAEZ,QAAO;;AAIX,SAAgB,mBAAmB,MAAwD;AACzF,KAAI,SAAS,OACX;AAEF,QAAO,WAAW,KAAK;;AAkBzB,MAAM,gBAAgB,IAAI,aAAa,CAAC,OAAO,QAAQ;;;;;;AAOvD,SAAgB,sBAAsB,OAAiC;CAErE,MAAM,OAAO,YADME,2BAAa,eAAe,aAAa,MAAM,CAAC,CAC/B;AACpC,QAAO,IAAI,QAAQ,WAAW,KAAK,KAAK,CAAC;;;;;;;AAQ3C,SAAgB,cAAc,SAA0B;AACtD,QAAO,QAAQ,WAAW,QAAQ;;;;;;;AAQpC,SAAgB,cAAc,SAA6B;AACzD,QAAO,IAAI,QAAQ,QAAQ,CAAC,UAAU"}
1
+ {"version":3,"file":"address.js","names":["sha512","HASH_BYTES_LENGTH","CHECKSUM_BYTE_LENGTH","arrayEqual","base32","concatArrays"],"sources":["../../../../packages/common/src/address.ts"],"sourcesContent":["import base32 from 'hi-base32'\nimport sha512 from 'js-sha512'\nimport { arrayEqual, concatArrays } from './array'\nimport { CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH } from './constants'\n\nexport const ALGORAND_ADDRESS_BYTE_LENGTH = 36\nexport const ALGORAND_CHECKSUM_BYTE_LENGTH = 4\nexport const ALGORAND_ADDRESS_LENGTH = 58\nexport const ALGORAND_ZERO_ADDRESS_STRING = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ'\n\nexport const MALFORMED_ADDRESS_ERROR_MSG = 'address seems to be malformed'\nexport const CHECKSUM_ADDRESS_ERROR_MSG = 'wrong checksum for address'\n\nexport function checksumFromPublicKey(publicKey: Uint8Array): Uint8Array {\n return Uint8Array.from(sha512.sha512_256.array(publicKey).slice(HASH_BYTES_LENGTH - CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH))\n}\n\nfunction genericHash(arr: sha512.Message) {\n return sha512.sha512_256.array(arr)\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('hex')\n}\n\nexport function encodeUint64(num: number | bigint) {\n const isInteger = typeof num === 'bigint' || Number.isInteger(num)\n\n if (!isInteger || num < 0 || num > BigInt('0xffffffffffffffff')) {\n throw new Error('Input is not a 64-bit unsigned integer')\n }\n\n const encoding = new Uint8Array(8)\n const view = new DataView(encoding.buffer)\n view.setBigUint64(0, BigInt(num))\n\n return encoding\n}\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nconst ADDR_SYMBOL = Symbol.for('algokit_common:Address')\n\n/**\n * Represents an Algorand address\n */\nexport class Address {\n /**\n * The binary form of the address. For standard accounts, this is the public key.\n */\n public readonly publicKey: Uint8Array;\n\n /** @internal */\n [ADDR_SYMBOL]: boolean\n\n /**\n * Create a new Address object from its binary form.\n * @param publicKey - The binary form of the address. Must be 32 bytes.\n */\n constructor(publicKey: Uint8Array) {\n this[ADDR_SYMBOL] = true\n if (publicKey.length !== ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: 0x${bytesToHex(publicKey)}, length ${publicKey.length}`)\n this.publicKey = publicKey\n }\n\n /**\n * Check if the address is equal to another address.\n */\n equals(other: Address): boolean {\n return other instanceof Address && arrayEqual(this.publicKey, other.publicKey)\n }\n\n /**\n * Compute the 4 byte checksum of the address.\n */\n checksum(): Uint8Array {\n return checksumFromPublicKey(this.publicKey)\n }\n\n /**\n * Encode the address into a string form.\n */\n toString(): string {\n const addr = base32.encode(concatArrays(this.publicKey, this.checksum()))\n return addr.slice(0, ALGORAND_ADDRESS_LENGTH) // removing the extra '===='\n }\n\n /**\n * Decode an address from a string.\n * @param address - The address to decode. Must be 58 characters long.\n * @returns An Address object corresponding to the input string.\n */\n static fromString(address: string): Address {\n if (typeof address !== 'string') throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected string, got ${typeof address}, ${address}`)\n if (address.length !== ALGORAND_ADDRESS_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected length ${ALGORAND_ADDRESS_LENGTH}, got ${address.length}: ${address}`)\n\n // try to decode\n const decoded = base32.decode.asBytes(address)\n // Sanity check\n if (decoded.length !== ALGORAND_ADDRESS_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected byte length ${ALGORAND_ADDRESS_BYTE_LENGTH}, got ${decoded.length}`)\n\n // Find publickey and checksum\n const pk = new Uint8Array(decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n const cs = new Uint8Array(decoded.slice(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, ALGORAND_ADDRESS_BYTE_LENGTH))\n const checksum = checksumFromPublicKey(pk)\n // Check if the checksum and the address are equal\n if (!arrayEqual(checksum, cs)) throw new Error(`${CHECKSUM_ADDRESS_ERROR_MSG}: ${address} (${cs}, ${checksum})`)\n\n return new Address(pk)\n }\n\n /**\n * Get the zero address.\n */\n static zeroAddress(): Address {\n return new Address(new Uint8Array(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n }\n}\n\n// Define Symbol.hasInstance outside the class to avoid Metro/Hermes parser issues\n// with static computed property names like `static [Symbol.hasInstance]()`\n// Also must handle Babel's _classCallCheck which uses instanceof before ADDR_SYMBOL is set\nObject.defineProperty(Address, Symbol.hasInstance, {\n value: function (obj: unknown): boolean {\n // First check prototype chain (handles Babel's _classCallCheck and normal instances)\n if (obj instanceof Object && Object.getPrototypeOf(obj) === Address.prototype) {\n return true\n }\n // Then check for the brand symbol (handles cross-realm/serialized instances)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Boolean(obj && typeof obj === 'object' && ADDR_SYMBOL in obj && (obj as any)[ADDR_SYMBOL])\n },\n})\n\nexport interface Addressable {\n addr: Readonly<Address>\n}\n\nexport type ReadableAddress = Addressable | Address | string\n\nexport function getAddress(addr: ReadableAddress): Address {\n if (typeof addr == 'string') {\n return Address.fromString(addr)\n } else if ('addr' in addr) {\n return addr.addr\n } else {\n return addr\n }\n}\n\nexport function getOptionalAddress(addr: ReadableAddress | undefined): Address | undefined {\n if (addr === undefined) {\n return undefined\n }\n return getAddress(addr)\n}\n\n/**\n * isValidAddress checks if a string is a valid Algorand address.\n * @param address - an Algorand address with checksum.\n * @returns true if valid, false otherwise\n */\nexport function isValidAddress(address: string): boolean {\n // Try to decode\n try {\n Address.fromString(address)\n } catch {\n return false\n }\n return true\n}\n\nconst APP_ID_PREFIX = new TextEncoder().encode('appID')\n\n/**\n * Get the escrow address of an application.\n * @param appID - The ID of the application.\n * @returns The address corresponding to that application's escrow account.\n */\nexport function getApplicationAddress(appID: number | bigint): Address {\n const toBeSigned = concatArrays(APP_ID_PREFIX, encodeUint64(appID))\n const hash = genericHash(toBeSigned)\n return new Address(Uint8Array.from(hash))\n}\n\n/**\n * decodeAddress takes an Algorand address in string form and decodes it into a Uint8Array.\n * @param address - an Algorand address with checksum.\n * @returns the decoded form of the address's public key and checksum\n */\nexport function decodeAddress(address: string): Address {\n return Address.fromString(address)\n}\n\n/**\n * encodeAddress takes an Algorand address as a Uint8Array and encodes it into a string with checksum.\n * @param address - a raw Algorand address\n * @returns the address and checksum encoded as a string.\n */\nexport function encodeAddress(address: Uint8Array): string {\n return new Address(address).toString()\n}\n"],"mappings":"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"}
@@ -86,10 +86,11 @@ var Address = class Address {
86
86
  static zeroAddress() {
87
87
  return new Address(new Uint8Array(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH));
88
88
  }
89
- static [Symbol.hasInstance](obj) {
90
- return Boolean(obj && typeof obj === "object" && ADDR_SYMBOL in obj && obj[ADDR_SYMBOL]);
91
- }
92
89
  };
90
+ Object.defineProperty(Address, Symbol.hasInstance, { value: function(obj) {
91
+ if (obj instanceof Object && Object.getPrototypeOf(obj) === Address.prototype) return true;
92
+ return Boolean(obj && typeof obj === "object" && ADDR_SYMBOL in obj && obj[ADDR_SYMBOL]);
93
+ } });
93
94
  function getAddress(addr) {
94
95
  if (typeof addr == "string") return Address.fromString(addr);
95
96
  else if ("addr" in addr) return addr.addr;
@@ -1 +1 @@
1
- {"version":3,"file":"address.mjs","names":[],"sources":["../../../../packages/common/src/address.ts"],"sourcesContent":["import base32 from 'hi-base32'\nimport sha512 from 'js-sha512'\nimport { arrayEqual, concatArrays } from './array'\nimport { CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH } from './constants'\n\nexport const ALGORAND_ADDRESS_BYTE_LENGTH = 36\nexport const ALGORAND_CHECKSUM_BYTE_LENGTH = 4\nexport const ALGORAND_ADDRESS_LENGTH = 58\nexport const ALGORAND_ZERO_ADDRESS_STRING = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ'\n\nexport const MALFORMED_ADDRESS_ERROR_MSG = 'address seems to be malformed'\nexport const CHECKSUM_ADDRESS_ERROR_MSG = 'wrong checksum for address'\n\nexport function checksumFromPublicKey(publicKey: Uint8Array): Uint8Array {\n return Uint8Array.from(sha512.sha512_256.array(publicKey).slice(HASH_BYTES_LENGTH - CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH))\n}\n\nfunction genericHash(arr: sha512.Message) {\n return sha512.sha512_256.array(arr)\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('hex')\n}\n\nexport function encodeUint64(num: number | bigint) {\n const isInteger = typeof num === 'bigint' || Number.isInteger(num)\n\n if (!isInteger || num < 0 || num > BigInt('0xffffffffffffffff')) {\n throw new Error('Input is not a 64-bit unsigned integer')\n }\n\n const encoding = new Uint8Array(8)\n const view = new DataView(encoding.buffer)\n view.setBigUint64(0, BigInt(num))\n\n return encoding\n}\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nconst ADDR_SYMBOL = Symbol.for('algokit_common:Address')\n\n/**\n * Represents an Algorand address\n */\nexport class Address {\n /**\n * The binary form of the address. For standard accounts, this is the public key.\n */\n public readonly publicKey: Uint8Array;\n\n /** @internal */\n [ADDR_SYMBOL]: boolean\n\n /**\n * Create a new Address object from its binary form.\n * @param publicKey - The binary form of the address. Must be 32 bytes.\n */\n constructor(publicKey: Uint8Array) {\n this[ADDR_SYMBOL] = true\n if (publicKey.length !== ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: 0x${bytesToHex(publicKey)}, length ${publicKey.length}`)\n this.publicKey = publicKey\n }\n\n /**\n * Check if the address is equal to another address.\n */\n equals(other: Address): boolean {\n return other instanceof Address && arrayEqual(this.publicKey, other.publicKey)\n }\n\n /**\n * Compute the 4 byte checksum of the address.\n */\n checksum(): Uint8Array {\n return checksumFromPublicKey(this.publicKey)\n }\n\n /**\n * Encode the address into a string form.\n */\n toString(): string {\n const addr = base32.encode(concatArrays(this.publicKey, this.checksum()))\n return addr.slice(0, ALGORAND_ADDRESS_LENGTH) // removing the extra '===='\n }\n\n /**\n * Decode an address from a string.\n * @param address - The address to decode. Must be 58 characters long.\n * @returns An Address object corresponding to the input string.\n */\n static fromString(address: string): Address {\n if (typeof address !== 'string') throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected string, got ${typeof address}, ${address}`)\n if (address.length !== ALGORAND_ADDRESS_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected length ${ALGORAND_ADDRESS_LENGTH}, got ${address.length}: ${address}`)\n\n // try to decode\n const decoded = base32.decode.asBytes(address)\n // Sanity check\n if (decoded.length !== ALGORAND_ADDRESS_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected byte length ${ALGORAND_ADDRESS_BYTE_LENGTH}, got ${decoded.length}`)\n\n // Find publickey and checksum\n const pk = new Uint8Array(decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n const cs = new Uint8Array(decoded.slice(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, ALGORAND_ADDRESS_BYTE_LENGTH))\n const checksum = checksumFromPublicKey(pk)\n // Check if the checksum and the address are equal\n if (!arrayEqual(checksum, cs)) throw new Error(`${CHECKSUM_ADDRESS_ERROR_MSG}: ${address} (${cs}, ${checksum})`)\n\n return new Address(pk)\n }\n\n /**\n * Get the zero address.\n */\n static zeroAddress(): Address {\n return new Address(new Uint8Array(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n }\n\n static [Symbol.hasInstance](obj: unknown) {\n return Boolean(obj && typeof obj === 'object' && ADDR_SYMBOL in obj && obj[ADDR_SYMBOL as keyof typeof obj])\n }\n}\n\nexport interface Addressable {\n addr: Readonly<Address>\n}\n\nexport type ReadableAddress = Addressable | Address | string\n\nexport function getAddress(addr: ReadableAddress): Address {\n if (typeof addr == 'string') {\n return Address.fromString(addr)\n } else if ('addr' in addr) {\n return addr.addr\n } else {\n return addr\n }\n}\n\nexport function getOptionalAddress(addr: ReadableAddress | undefined): Address | undefined {\n if (addr === undefined) {\n return undefined\n }\n return getAddress(addr)\n}\n\n/**\n * isValidAddress checks if a string is a valid Algorand address.\n * @param address - an Algorand address with checksum.\n * @returns true if valid, false otherwise\n */\nexport function isValidAddress(address: string): boolean {\n // Try to decode\n try {\n Address.fromString(address)\n } catch {\n return false\n }\n return true\n}\n\nconst APP_ID_PREFIX = new TextEncoder().encode('appID')\n\n/**\n * Get the escrow address of an application.\n * @param appID - The ID of the application.\n * @returns The address corresponding to that application's escrow account.\n */\nexport function getApplicationAddress(appID: number | bigint): Address {\n const toBeSigned = concatArrays(APP_ID_PREFIX, encodeUint64(appID))\n const hash = genericHash(toBeSigned)\n return new Address(Uint8Array.from(hash))\n}\n\n/**\n * decodeAddress takes an Algorand address in string form and decodes it into a Uint8Array.\n * @param address - an Algorand address with checksum.\n * @returns the decoded form of the address's public key and checksum\n */\nexport function decodeAddress(address: string): Address {\n return Address.fromString(address)\n}\n\n/**\n * encodeAddress takes an Algorand address as a Uint8Array and encodes it into a string with checksum.\n * @param address - a raw Algorand address\n * @returns the address and checksum encoded as a string.\n */\nexport function encodeAddress(address: Uint8Array): string {\n return new Address(address).toString()\n}\n"],"mappings":";;;;;;AAKA,MAAa,+BAA+B;AAC5C,MAAa,gCAAgC;AAC7C,MAAa,0BAA0B;AACvC,MAAa,+BAA+B;AAE5C,MAAa,8BAA8B;AAC3C,MAAa,6BAA6B;AAE1C,SAAgB,sBAAsB,WAAmC;AACvE,QAAO,WAAW,KAAK,OAAO,WAAW,MAAM,UAAU,CAAC,MAAM,oBAAoB,sBAAsB,kBAAkB,CAAC;;AAG/H,SAAS,YAAY,KAAqB;AACxC,QAAO,OAAO,WAAW,MAAM,IAAI;;AAGrC,SAAS,WAAW,OAA2B;AAC7C,QAAO,OAAO,KAAK,MAAM,CAAC,SAAS,MAAM;;AAG3C,SAAgB,aAAa,KAAsB;AAGjD,KAAI,EAFc,OAAO,QAAQ,YAAY,OAAO,UAAU,IAAI,KAEhD,MAAM,KAAK,MAAM,OAAO,qBAAqB,CAC7D,OAAM,IAAI,MAAM,yCAAyC;CAG3D,MAAM,WAAW,IAAI,WAAW,EAAE;AAElC,CADa,IAAI,SAAS,SAAS,OAAO,CACrC,aAAa,GAAG,OAAO,IAAI,CAAC;AAEjC,QAAO;;;AAIT,MAAM,cAAc,OAAO,IAAI,yBAAyB;;;;AAKxD,IAAa,UAAb,MAAa,QAAQ;;;;CAInB,AAAgB;;CAGhB,CAAC;;;;;CAMD,YAAY,WAAuB;AACjC,OAAK,eAAe;AACpB,MAAI,UAAU,WAAW,+BAA+B,8BACtD,OAAM,IAAI,MAAM,GAAG,4BAA4B,MAAM,WAAW,UAAU,CAAC,WAAW,UAAU,SAAS;AAC3G,OAAK,YAAY;;;;;CAMnB,OAAO,OAAyB;AAC9B,SAAO,iBAAiB,WAAW,WAAW,KAAK,WAAW,MAAM,UAAU;;;;;CAMhF,WAAuB;AACrB,SAAO,sBAAsB,KAAK,UAAU;;;;;CAM9C,WAAmB;AAEjB,SADa,OAAO,OAAO,aAAa,KAAK,WAAW,KAAK,UAAU,CAAC,CAAC,CAC7D,MAAM,GAAG,wBAAwB;;;;;;;CAQ/C,OAAO,WAAW,SAA0B;AAC1C,MAAI,OAAO,YAAY,SAAU,OAAM,IAAI,MAAM,GAAG,4BAA4B,yBAAyB,OAAO,QAAQ,IAAI,UAAU;AACtI,MAAI,QAAQ,WAAW,wBACrB,OAAM,IAAI,MAAM,GAAG,4BAA4B,oBAAoB,wBAAwB,QAAQ,QAAQ,OAAO,IAAI,UAAU;EAGlI,MAAM,UAAU,OAAO,OAAO,QAAQ,QAAQ;AAE9C,MAAI,QAAQ,WAAW,6BACrB,OAAM,IAAI,MAAM,GAAG,4BAA4B,yBAAyB,6BAA6B,QAAQ,QAAQ,SAAS;EAGhI,MAAM,KAAK,IAAI,WAAW,QAAQ,MAAM,GAAG,+BAA+B,8BAA8B,CAAC;EACzG,MAAM,KAAK,IAAI,WAAW,QAAQ,MAAM,+BAA+B,+BAA+B,6BAA6B,CAAC;EACpI,MAAM,WAAW,sBAAsB,GAAG;AAE1C,MAAI,CAAC,WAAW,UAAU,GAAG,CAAE,OAAM,IAAI,MAAM,GAAG,2BAA2B,IAAI,QAAQ,IAAI,GAAG,IAAI,SAAS,GAAG;AAEhH,SAAO,IAAI,QAAQ,GAAG;;;;;CAMxB,OAAO,cAAuB;AAC5B,SAAO,IAAI,QAAQ,IAAI,WAAW,+BAA+B,8BAA8B,CAAC;;CAGlG,QAAQ,OAAO,aAAa,KAAc;AACxC,SAAO,QAAQ,OAAO,OAAO,QAAQ,YAAY,eAAe,OAAO,IAAI,aAAiC;;;AAUhH,SAAgB,WAAW,MAAgC;AACzD,KAAI,OAAO,QAAQ,SACjB,QAAO,QAAQ,WAAW,KAAK;UACtB,UAAU,KACnB,QAAO,KAAK;KAEZ,QAAO;;AAIX,SAAgB,mBAAmB,MAAwD;AACzF,KAAI,SAAS,OACX;AAEF,QAAO,WAAW,KAAK;;AAkBzB,MAAM,gBAAgB,IAAI,aAAa,CAAC,OAAO,QAAQ;;;;;;AAOvD,SAAgB,sBAAsB,OAAiC;CAErE,MAAM,OAAO,YADM,aAAa,eAAe,aAAa,MAAM,CAAC,CAC/B;AACpC,QAAO,IAAI,QAAQ,WAAW,KAAK,KAAK,CAAC;;;;;;;AAQ3C,SAAgB,cAAc,SAA0B;AACtD,QAAO,QAAQ,WAAW,QAAQ;;;;;;;AAQpC,SAAgB,cAAc,SAA6B;AACzD,QAAO,IAAI,QAAQ,QAAQ,CAAC,UAAU"}
1
+ {"version":3,"file":"address.mjs","names":[],"sources":["../../../../packages/common/src/address.ts"],"sourcesContent":["import base32 from 'hi-base32'\nimport sha512 from 'js-sha512'\nimport { arrayEqual, concatArrays } from './array'\nimport { CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH } from './constants'\n\nexport const ALGORAND_ADDRESS_BYTE_LENGTH = 36\nexport const ALGORAND_CHECKSUM_BYTE_LENGTH = 4\nexport const ALGORAND_ADDRESS_LENGTH = 58\nexport const ALGORAND_ZERO_ADDRESS_STRING = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ'\n\nexport const MALFORMED_ADDRESS_ERROR_MSG = 'address seems to be malformed'\nexport const CHECKSUM_ADDRESS_ERROR_MSG = 'wrong checksum for address'\n\nexport function checksumFromPublicKey(publicKey: Uint8Array): Uint8Array {\n return Uint8Array.from(sha512.sha512_256.array(publicKey).slice(HASH_BYTES_LENGTH - CHECKSUM_BYTE_LENGTH, HASH_BYTES_LENGTH))\n}\n\nfunction genericHash(arr: sha512.Message) {\n return sha512.sha512_256.array(arr)\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('hex')\n}\n\nexport function encodeUint64(num: number | bigint) {\n const isInteger = typeof num === 'bigint' || Number.isInteger(num)\n\n if (!isInteger || num < 0 || num > BigInt('0xffffffffffffffff')) {\n throw new Error('Input is not a 64-bit unsigned integer')\n }\n\n const encoding = new Uint8Array(8)\n const view = new DataView(encoding.buffer)\n view.setBigUint64(0, BigInt(num))\n\n return encoding\n}\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nconst ADDR_SYMBOL = Symbol.for('algokit_common:Address')\n\n/**\n * Represents an Algorand address\n */\nexport class Address {\n /**\n * The binary form of the address. For standard accounts, this is the public key.\n */\n public readonly publicKey: Uint8Array;\n\n /** @internal */\n [ADDR_SYMBOL]: boolean\n\n /**\n * Create a new Address object from its binary form.\n * @param publicKey - The binary form of the address. Must be 32 bytes.\n */\n constructor(publicKey: Uint8Array) {\n this[ADDR_SYMBOL] = true\n if (publicKey.length !== ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: 0x${bytesToHex(publicKey)}, length ${publicKey.length}`)\n this.publicKey = publicKey\n }\n\n /**\n * Check if the address is equal to another address.\n */\n equals(other: Address): boolean {\n return other instanceof Address && arrayEqual(this.publicKey, other.publicKey)\n }\n\n /**\n * Compute the 4 byte checksum of the address.\n */\n checksum(): Uint8Array {\n return checksumFromPublicKey(this.publicKey)\n }\n\n /**\n * Encode the address into a string form.\n */\n toString(): string {\n const addr = base32.encode(concatArrays(this.publicKey, this.checksum()))\n return addr.slice(0, ALGORAND_ADDRESS_LENGTH) // removing the extra '===='\n }\n\n /**\n * Decode an address from a string.\n * @param address - The address to decode. Must be 58 characters long.\n * @returns An Address object corresponding to the input string.\n */\n static fromString(address: string): Address {\n if (typeof address !== 'string') throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected string, got ${typeof address}, ${address}`)\n if (address.length !== ALGORAND_ADDRESS_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected length ${ALGORAND_ADDRESS_LENGTH}, got ${address.length}: ${address}`)\n\n // try to decode\n const decoded = base32.decode.asBytes(address)\n // Sanity check\n if (decoded.length !== ALGORAND_ADDRESS_BYTE_LENGTH)\n throw new Error(`${MALFORMED_ADDRESS_ERROR_MSG}: expected byte length ${ALGORAND_ADDRESS_BYTE_LENGTH}, got ${decoded.length}`)\n\n // Find publickey and checksum\n const pk = new Uint8Array(decoded.slice(0, ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n const cs = new Uint8Array(decoded.slice(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH, ALGORAND_ADDRESS_BYTE_LENGTH))\n const checksum = checksumFromPublicKey(pk)\n // Check if the checksum and the address are equal\n if (!arrayEqual(checksum, cs)) throw new Error(`${CHECKSUM_ADDRESS_ERROR_MSG}: ${address} (${cs}, ${checksum})`)\n\n return new Address(pk)\n }\n\n /**\n * Get the zero address.\n */\n static zeroAddress(): Address {\n return new Address(new Uint8Array(ALGORAND_ADDRESS_BYTE_LENGTH - ALGORAND_CHECKSUM_BYTE_LENGTH))\n }\n}\n\n// Define Symbol.hasInstance outside the class to avoid Metro/Hermes parser issues\n// with static computed property names like `static [Symbol.hasInstance]()`\n// Also must handle Babel's _classCallCheck which uses instanceof before ADDR_SYMBOL is set\nObject.defineProperty(Address, Symbol.hasInstance, {\n value: function (obj: unknown): boolean {\n // First check prototype chain (handles Babel's _classCallCheck and normal instances)\n if (obj instanceof Object && Object.getPrototypeOf(obj) === Address.prototype) {\n return true\n }\n // Then check for the brand symbol (handles cross-realm/serialized instances)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Boolean(obj && typeof obj === 'object' && ADDR_SYMBOL in obj && (obj as any)[ADDR_SYMBOL])\n },\n})\n\nexport interface Addressable {\n addr: Readonly<Address>\n}\n\nexport type ReadableAddress = Addressable | Address | string\n\nexport function getAddress(addr: ReadableAddress): Address {\n if (typeof addr == 'string') {\n return Address.fromString(addr)\n } else if ('addr' in addr) {\n return addr.addr\n } else {\n return addr\n }\n}\n\nexport function getOptionalAddress(addr: ReadableAddress | undefined): Address | undefined {\n if (addr === undefined) {\n return undefined\n }\n return getAddress(addr)\n}\n\n/**\n * isValidAddress checks if a string is a valid Algorand address.\n * @param address - an Algorand address with checksum.\n * @returns true if valid, false otherwise\n */\nexport function isValidAddress(address: string): boolean {\n // Try to decode\n try {\n Address.fromString(address)\n } catch {\n return false\n }\n return true\n}\n\nconst APP_ID_PREFIX = new TextEncoder().encode('appID')\n\n/**\n * Get the escrow address of an application.\n * @param appID - The ID of the application.\n * @returns The address corresponding to that application's escrow account.\n */\nexport function getApplicationAddress(appID: number | bigint): Address {\n const toBeSigned = concatArrays(APP_ID_PREFIX, encodeUint64(appID))\n const hash = genericHash(toBeSigned)\n return new Address(Uint8Array.from(hash))\n}\n\n/**\n * decodeAddress takes an Algorand address in string form and decodes it into a Uint8Array.\n * @param address - an Algorand address with checksum.\n * @returns the decoded form of the address's public key and checksum\n */\nexport function decodeAddress(address: string): Address {\n return Address.fromString(address)\n}\n\n/**\n * encodeAddress takes an Algorand address as a Uint8Array and encodes it into a string with checksum.\n * @param address - a raw Algorand address\n * @returns the address and checksum encoded as a string.\n */\nexport function encodeAddress(address: Uint8Array): string {\n return new Address(address).toString()\n}\n"],"mappings":"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"}
@@ -233,7 +233,6 @@ declare class Transaction implements TransactionParams {
233
233
  * Get the transaction ID as a base32-encoded string.
234
234
  */
235
235
  txId(): string;
236
- static [Symbol.hasInstance](obj: unknown): boolean;
237
236
  }
238
237
  /**
239
238
  * Codec for Transaction class.
@@ -157,10 +157,11 @@ var Transaction = class {
157
157
  const rawTxId = this.rawTxId();
158
158
  return hi_base32.default.encode(rawTxId).slice(0, require_constants.TRANSACTION_ID_LENGTH);
159
159
  }
160
- static [Symbol.hasInstance](obj) {
161
- return Boolean(obj && typeof obj === "object" && TXN_SYMBOL in obj && obj[TXN_SYMBOL]);
162
- }
163
160
  };
161
+ Object.defineProperty(Transaction, Symbol.hasInstance, { value: function(obj) {
162
+ if (obj instanceof Object && Object.getPrototypeOf(obj) === Transaction.prototype) return true;
163
+ return Boolean(obj && typeof obj === "object" && TXN_SYMBOL in obj && obj[TXN_SYMBOL]);
164
+ } });
164
165
  /**
165
166
  * Codec for Transaction class.
166
167
  * Handles encoding/decoding between Transaction class instances and wire format.
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.js","names":["hash","base32","TRANSACTION_ID_LENGTH","Codec","TransactionType","Address","transactionParamsCodec","concatArrays","TRANSACTION_DOMAIN_SEPARATOR","validateAssetTransferTransaction","validateAssetConfigTransaction","validateAppCallTransaction","validateKeyRegistrationTransaction","validateAssetFreezeTransaction","getValidationErrorMessage","encodeMsgpack","decodeMsgpack","SIGNATURE_ENCODING_INCR","MAX_TRANSACTION_GROUP_SIZE","TRANSACTION_GROUP_DOMAIN_SEPARATOR"],"sources":["../../../../../packages/transact/src/transactions/transaction.ts"],"sourcesContent":["import type { EncodingFormat, WireObject } from '@algorandfoundation/algokit-common'\nimport {\n Address,\n Codec,\n MAX_TRANSACTION_GROUP_SIZE,\n SIGNATURE_ENCODING_INCR,\n TRANSACTION_DOMAIN_SEPARATOR,\n TRANSACTION_GROUP_DOMAIN_SEPARATOR,\n TRANSACTION_ID_LENGTH,\n concatArrays,\n decodeMsgpack,\n encodeMsgpack,\n hash,\n} from '@algorandfoundation/algokit-common'\nimport base32 from 'hi-base32'\nimport { AppCallTransactionFields, validateAppCallTransaction } from './app-call'\nimport { AssetConfigTransactionFields, validateAssetConfigTransaction } from './asset-config'\nimport { AssetFreezeTransactionFields, validateAssetFreezeTransaction } from './asset-freeze'\nimport { AssetTransferTransactionFields, validateAssetTransferTransaction } from './asset-transfer'\nimport { TransactionValidationError, getValidationErrorMessage } from './common'\nimport { HeartbeatTransactionFields } from './heartbeat'\nimport { KeyRegistrationTransactionFields, validateKeyRegistrationTransaction } from './key-registration'\nimport { PaymentTransactionFields } from './payment'\nimport { StateProofTransactionFields } from './state-proof'\nimport { transactionParamsCodec } from './transaction-meta'\nimport { TransactionType } from './transaction-type'\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nexport const TXN_SYMBOL = Symbol.for('algokit_transact:Transaction')\n\n/**\n * Represents the parameters for a complete Algorand transaction.\n *\n * This structure contains the fields that are present in every transaction,\n * regardless of transaction type, plus transaction-type-specific fields.\n */\nexport type TransactionParams = {\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n}\n\n/**\n * Represents a complete Algorand transaction.\n */\nexport class Transaction implements TransactionParams {\n /** @internal */\n [TXN_SYMBOL]: boolean\n\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n\n constructor(params: TransactionParams) {\n this[TXN_SYMBOL] = true\n this.type = params.type\n this.sender = params.sender\n this.fee = params.fee\n this.firstValid = params.firstValid\n this.lastValid = params.lastValid\n this.genesisHash = params.genesisHash\n this.genesisId = params.genesisId\n this.note = params.note\n this.rekeyTo = params.rekeyTo\n this.lease = params.lease\n this.group = params.group\n this.payment = params.payment\n this.assetTransfer = params.assetTransfer\n this.assetConfig = params.assetConfig\n this.appCall = params.appCall\n this.keyRegistration = params.keyRegistration\n this.assetFreeze = params.assetFreeze\n this.heartbeat = params.heartbeat\n this.stateProof = params.stateProof\n }\n\n private rawTxId(): Uint8Array {\n if (this.genesisHash === undefined) {\n throw new Error('Cannot compute transaction id without genesis hash')\n }\n\n const encodedBytes = encodeTransaction(this)\n return hash(encodedBytes)\n }\n\n /**\n * Get the transaction ID as a base32-encoded string.\n */\n txId(): string {\n const rawTxId = this.rawTxId()\n\n return base32.encode(rawTxId).slice(0, TRANSACTION_ID_LENGTH)\n }\n\n static [Symbol.hasInstance](obj: unknown) {\n return Boolean(obj && typeof obj === 'object' && TXN_SYMBOL in obj && obj[TXN_SYMBOL as keyof typeof obj])\n }\n}\n\n/**\n * Codec for Transaction class.\n * Handles encoding/decoding between Transaction class instances and wire format.\n */\nclass TransactionCodec extends Codec<Transaction, Record<string, unknown>, WireObject> {\n public defaultValue(): Transaction {\n return new Transaction({\n type: TransactionType.Unknown,\n sender: Address.zeroAddress(),\n firstValid: 0n,\n lastValid: 0n,\n })\n }\n\n protected toEncoded(value: Transaction, format: EncodingFormat): Record<string, unknown> {\n return transactionParamsCodec.encode({ ...value }, format)\n }\n\n protected fromEncoded(value: WireObject, format: EncodingFormat): Transaction {\n const params = transactionParamsCodec.decode(value, format)\n return new Transaction(params)\n }\n\n public isDefaultValue(_: Transaction): boolean {\n return false\n }\n}\n\nexport const transactionCodec = new TransactionCodec()\n\nexport type FeeParams = {\n feePerByte: bigint\n minFee: bigint\n extraFee?: bigint\n maxFee?: bigint\n}\n\n/**\n * Get the transaction type from the encoded transaction.\n * This is particularly useful when decoding a transaction that has an unknown type\n */\nexport function getEncodedTransactionType(encoded_transaction: Uint8Array): TransactionType {\n const decoded = decodeTransaction(encoded_transaction)\n return decoded.type\n}\n\n/**\n * Encode the transaction with the domain separation (e.g. \"TX\") prefix\n *\n * @param transaction - The transaction to encode\n * @returns The MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransaction(transaction: Transaction): Uint8Array {\n const rawBytes = encodeTransactionRaw(transaction)\n\n // Add domain separation prefix\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n return concatArrays(prefixBytes, rawBytes)\n}\n\n/**\n * Encode transactions with the domain separation (e.g. \"TX\") prefix\n *\n * @param transactions - A collection of transactions to encode\n * @returns A collection of MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransactions(transactions: Transaction[]): Uint8Array[] {\n return transactions.map((tx) => encodeTransaction(tx))\n}\n\n/**\n * Validate a transaction\n */\nexport function validateTransaction(transaction: Transaction): void {\n // Validate that only one transaction type specific field is set\n const typeFields = [\n transaction.payment,\n transaction.assetTransfer,\n transaction.assetConfig,\n transaction.appCall,\n transaction.keyRegistration,\n transaction.assetFreeze,\n transaction.heartbeat,\n transaction.stateProof,\n ]\n\n const setFieldsCount = typeFields.filter((field) => field !== undefined).length\n\n if (setFieldsCount > 1) {\n throw new Error('Multiple transaction type specific fields set')\n }\n\n // Perform type-specific validation where applicable\n let typeName = 'Transaction'\n const errors = new Array<TransactionValidationError>()\n if (transaction.assetTransfer) {\n typeName = 'Asset transfer'\n errors.push(...validateAssetTransferTransaction(transaction.assetTransfer))\n } else if (transaction.assetConfig) {\n typeName = 'Asset config'\n errors.push(...validateAssetConfigTransaction(transaction.assetConfig))\n } else if (transaction.appCall) {\n typeName = 'App call'\n errors.push(...validateAppCallTransaction(transaction.appCall))\n } else if (transaction.keyRegistration) {\n typeName = 'Key registration'\n errors.push(...validateKeyRegistrationTransaction(transaction.keyRegistration))\n } else if (transaction.assetFreeze) {\n typeName = 'Asset freeze'\n errors.push(...validateAssetFreezeTransaction(transaction.assetFreeze))\n }\n\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => getValidationErrorMessage(e))\n throw new Error(`${typeName} validation failed: ${errorMessages.join('\\n')}`)\n }\n}\n\n/**\n * Encode the transaction without the domain separation (e.g. \"TX\") prefix\n * This is useful for encoding the transaction for signing with tools that automatically add \"TX\" prefix to the transaction bytes.\n */\nexport function encodeTransactionRaw(transaction: Transaction): Uint8Array {\n const encodingData = transactionCodec.encode(transaction, 'msgpack')\n return encodeMsgpack(encodingData)\n}\n\n/**\n * Decodes MsgPack bytes into a transaction.\n *\n * # Parameters\n * * `encoded_transaction` - MsgPack encoded bytes representing a transaction.\n *\n * # Returns\n * A decoded transaction or an error if decoding fails.\n */\nexport function decodeTransaction(encoded_transaction: Uint8Array): Transaction {\n if (encoded_transaction.length === 0) {\n throw new Error('attempted to decode 0 bytes')\n }\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n // Check if the transaction has the domain separation prefix\n let hasPrefix = true\n if (encoded_transaction.length < prefixBytes.length) {\n hasPrefix = false\n } else {\n for (let i = 0; i < prefixBytes.length; i++) {\n if (encoded_transaction[i] !== prefixBytes[i]) {\n hasPrefix = false\n break\n }\n }\n }\n\n const decodedData = decodeMsgpack(hasPrefix ? encoded_transaction.slice(prefixBytes.length) : encoded_transaction)\n return transactionCodec.decode(decodedData, 'msgpack')\n}\n\n/**\n * Decodes a collection of MsgPack bytes into a transaction collection.\n *\n * # Parameters\n * * `encoded_transaction` - A collection of MsgPack encoded bytes, each representing a transaction.\n *\n * # Returns\n * A collection of decoded transactions or an error if decoding fails.\n */\nexport function decodeTransactions(encoded_transactions: Uint8Array[]): Transaction[] {\n return encoded_transactions.map((et) => decodeTransaction(et))\n}\n\n/**\n * Return the size of the transaction in bytes as if it was already signed and encoded.\n * This is useful for estimating the fee for the transaction.\n */\nexport function estimateTransactionSize(transaction: Transaction): bigint {\n const encoded = encodeTransactionRaw(transaction)\n return BigInt(encoded.length + SIGNATURE_ENCODING_INCR)\n}\n\n/**\n * Groups a collection of transactions by calculating and assigning the group to each transaction.\n */\nexport function groupTransactions(transactions: Transaction[]): Transaction[] {\n const group = computeGroup(transactions)\n return transactions.map(\n (tx) =>\n new Transaction({\n ...tx,\n group,\n }),\n )\n}\n\nexport function assignFee(transaction: Transaction, feeParams: FeeParams): Transaction {\n const fee = calculateFee(transaction, feeParams)\n return new Transaction({\n ...transaction,\n fee,\n })\n}\n\nfunction computeGroup(transactions: Transaction[]): Uint8Array {\n if (transactions.length === 0) {\n throw new Error('Transaction group size cannot be 0')\n }\n\n if (transactions.length > MAX_TRANSACTION_GROUP_SIZE) {\n throw new Error(`Transaction group size exceeds the max limit of ${MAX_TRANSACTION_GROUP_SIZE}`)\n }\n\n const txHashes = transactions.map((tx) => {\n if (tx.group) {\n throw new Error('Transactions must not already be grouped')\n }\n\n const encodedBytes = encodeTransaction(tx)\n return hash(encodedBytes)\n })\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_GROUP_DOMAIN_SEPARATOR)\n const encodedBytes = encodeMsgpack({\n txlist: txHashes,\n })\n\n const prefixedBytes = concatArrays(prefixBytes, encodedBytes)\n return hash(prefixedBytes)\n}\n\nexport function calculateFee(transaction: Transaction, feeParams: FeeParams): bigint {\n let calculatedFee = 0n\n\n if (feeParams.feePerByte > 0n) {\n const estimatedSize = estimateTransactionSize(transaction)\n calculatedFee = feeParams.feePerByte * BigInt(estimatedSize)\n }\n\n if (calculatedFee < feeParams.minFee) {\n calculatedFee = feeParams.minFee\n }\n\n if (feeParams.extraFee) {\n calculatedFee += feeParams.extraFee\n }\n\n if (feeParams.maxFee && calculatedFee > feeParams.maxFee) {\n throw new Error(`Transaction fee ${calculatedFee} µALGO is greater than maxFee ${feeParams.maxFee} µALGO`)\n }\n\n return calculatedFee\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transaction.js","names":["hash","base32","TRANSACTION_ID_LENGTH","Codec","TransactionType","Address","transactionParamsCodec","concatArrays","TRANSACTION_DOMAIN_SEPARATOR","validateAssetTransferTransaction","validateAssetConfigTransaction","validateAppCallTransaction","validateKeyRegistrationTransaction","validateAssetFreezeTransaction","getValidationErrorMessage","encodeMsgpack","decodeMsgpack","SIGNATURE_ENCODING_INCR","MAX_TRANSACTION_GROUP_SIZE","TRANSACTION_GROUP_DOMAIN_SEPARATOR"],"sources":["../../../../../packages/transact/src/transactions/transaction.ts"],"sourcesContent":["import type { EncodingFormat, WireObject } from '@algorandfoundation/algokit-common'\nimport {\n Address,\n Codec,\n MAX_TRANSACTION_GROUP_SIZE,\n SIGNATURE_ENCODING_INCR,\n TRANSACTION_DOMAIN_SEPARATOR,\n TRANSACTION_GROUP_DOMAIN_SEPARATOR,\n TRANSACTION_ID_LENGTH,\n concatArrays,\n decodeMsgpack,\n encodeMsgpack,\n hash,\n} from '@algorandfoundation/algokit-common'\nimport base32 from 'hi-base32'\nimport { AppCallTransactionFields, validateAppCallTransaction } from './app-call'\nimport { AssetConfigTransactionFields, validateAssetConfigTransaction } from './asset-config'\nimport { AssetFreezeTransactionFields, validateAssetFreezeTransaction } from './asset-freeze'\nimport { AssetTransferTransactionFields, validateAssetTransferTransaction } from './asset-transfer'\nimport { TransactionValidationError, getValidationErrorMessage } from './common'\nimport { HeartbeatTransactionFields } from './heartbeat'\nimport { KeyRegistrationTransactionFields, validateKeyRegistrationTransaction } from './key-registration'\nimport { PaymentTransactionFields } from './payment'\nimport { StateProofTransactionFields } from './state-proof'\nimport { transactionParamsCodec } from './transaction-meta'\nimport { TransactionType } from './transaction-type'\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nexport const TXN_SYMBOL = Symbol.for('algokit_transact:Transaction')\n\n/**\n * Represents the parameters for a complete Algorand transaction.\n *\n * This structure contains the fields that are present in every transaction,\n * regardless of transaction type, plus transaction-type-specific fields.\n */\nexport type TransactionParams = {\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n}\n\n/**\n * Represents a complete Algorand transaction.\n */\nexport class Transaction implements TransactionParams {\n /** @internal */\n [TXN_SYMBOL]: boolean\n\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n\n constructor(params: TransactionParams) {\n this[TXN_SYMBOL] = true\n this.type = params.type\n this.sender = params.sender\n this.fee = params.fee\n this.firstValid = params.firstValid\n this.lastValid = params.lastValid\n this.genesisHash = params.genesisHash\n this.genesisId = params.genesisId\n this.note = params.note\n this.rekeyTo = params.rekeyTo\n this.lease = params.lease\n this.group = params.group\n this.payment = params.payment\n this.assetTransfer = params.assetTransfer\n this.assetConfig = params.assetConfig\n this.appCall = params.appCall\n this.keyRegistration = params.keyRegistration\n this.assetFreeze = params.assetFreeze\n this.heartbeat = params.heartbeat\n this.stateProof = params.stateProof\n }\n\n private rawTxId(): Uint8Array {\n if (this.genesisHash === undefined) {\n throw new Error('Cannot compute transaction id without genesis hash')\n }\n\n const encodedBytes = encodeTransaction(this)\n return hash(encodedBytes)\n }\n\n /**\n * Get the transaction ID as a base32-encoded string.\n */\n txId(): string {\n const rawTxId = this.rawTxId()\n\n return base32.encode(rawTxId).slice(0, TRANSACTION_ID_LENGTH)\n }\n}\n\n// Define Symbol.hasInstance outside the class to avoid Metro/Hermes parser issues\n// with static computed property names like `static [Symbol.hasInstance]()`\n// Also must handle Babel's _classCallCheck which uses instanceof before TXN_SYMBOL is set\nObject.defineProperty(Transaction, Symbol.hasInstance, {\n value: function (obj: unknown): boolean {\n // First check prototype chain (handles Babel's _classCallCheck and normal instances)\n if (obj instanceof Object && Object.getPrototypeOf(obj) === Transaction.prototype) {\n return true\n }\n // Then check for the brand symbol (handles cross-realm/serialized instances)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Boolean(obj && typeof obj === 'object' && TXN_SYMBOL in obj && (obj as any)[TXN_SYMBOL])\n },\n})\n\n/**\n * Codec for Transaction class.\n * Handles encoding/decoding between Transaction class instances and wire format.\n */\nclass TransactionCodec extends Codec<Transaction, Record<string, unknown>, WireObject> {\n public defaultValue(): Transaction {\n return new Transaction({\n type: TransactionType.Unknown,\n sender: Address.zeroAddress(),\n firstValid: 0n,\n lastValid: 0n,\n })\n }\n\n protected toEncoded(value: Transaction, format: EncodingFormat): Record<string, unknown> {\n return transactionParamsCodec.encode({ ...value }, format)\n }\n\n protected fromEncoded(value: WireObject, format: EncodingFormat): Transaction {\n const params = transactionParamsCodec.decode(value, format)\n return new Transaction(params)\n }\n\n public isDefaultValue(_: Transaction): boolean {\n return false\n }\n}\n\nexport const transactionCodec = new TransactionCodec()\n\nexport type FeeParams = {\n feePerByte: bigint\n minFee: bigint\n extraFee?: bigint\n maxFee?: bigint\n}\n\n/**\n * Get the transaction type from the encoded transaction.\n * This is particularly useful when decoding a transaction that has an unknown type\n */\nexport function getEncodedTransactionType(encoded_transaction: Uint8Array): TransactionType {\n const decoded = decodeTransaction(encoded_transaction)\n return decoded.type\n}\n\n/**\n * Encode the transaction with the domain separation (e.g. \"TX\") prefix\n *\n * @param transaction - The transaction to encode\n * @returns The MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransaction(transaction: Transaction): Uint8Array {\n const rawBytes = encodeTransactionRaw(transaction)\n\n // Add domain separation prefix\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n return concatArrays(prefixBytes, rawBytes)\n}\n\n/**\n * Encode transactions with the domain separation (e.g. \"TX\") prefix\n *\n * @param transactions - A collection of transactions to encode\n * @returns A collection of MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransactions(transactions: Transaction[]): Uint8Array[] {\n return transactions.map((tx) => encodeTransaction(tx))\n}\n\n/**\n * Validate a transaction\n */\nexport function validateTransaction(transaction: Transaction): void {\n // Validate that only one transaction type specific field is set\n const typeFields = [\n transaction.payment,\n transaction.assetTransfer,\n transaction.assetConfig,\n transaction.appCall,\n transaction.keyRegistration,\n transaction.assetFreeze,\n transaction.heartbeat,\n transaction.stateProof,\n ]\n\n const setFieldsCount = typeFields.filter((field) => field !== undefined).length\n\n if (setFieldsCount > 1) {\n throw new Error('Multiple transaction type specific fields set')\n }\n\n // Perform type-specific validation where applicable\n let typeName = 'Transaction'\n const errors = new Array<TransactionValidationError>()\n if (transaction.assetTransfer) {\n typeName = 'Asset transfer'\n errors.push(...validateAssetTransferTransaction(transaction.assetTransfer))\n } else if (transaction.assetConfig) {\n typeName = 'Asset config'\n errors.push(...validateAssetConfigTransaction(transaction.assetConfig))\n } else if (transaction.appCall) {\n typeName = 'App call'\n errors.push(...validateAppCallTransaction(transaction.appCall))\n } else if (transaction.keyRegistration) {\n typeName = 'Key registration'\n errors.push(...validateKeyRegistrationTransaction(transaction.keyRegistration))\n } else if (transaction.assetFreeze) {\n typeName = 'Asset freeze'\n errors.push(...validateAssetFreezeTransaction(transaction.assetFreeze))\n }\n\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => getValidationErrorMessage(e))\n throw new Error(`${typeName} validation failed: ${errorMessages.join('\\n')}`)\n }\n}\n\n/**\n * Encode the transaction without the domain separation (e.g. \"TX\") prefix\n * This is useful for encoding the transaction for signing with tools that automatically add \"TX\" prefix to the transaction bytes.\n */\nexport function encodeTransactionRaw(transaction: Transaction): Uint8Array {\n const encodingData = transactionCodec.encode(transaction, 'msgpack')\n return encodeMsgpack(encodingData)\n}\n\n/**\n * Decodes MsgPack bytes into a transaction.\n *\n * # Parameters\n * * `encoded_transaction` - MsgPack encoded bytes representing a transaction.\n *\n * # Returns\n * A decoded transaction or an error if decoding fails.\n */\nexport function decodeTransaction(encoded_transaction: Uint8Array): Transaction {\n if (encoded_transaction.length === 0) {\n throw new Error('attempted to decode 0 bytes')\n }\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n // Check if the transaction has the domain separation prefix\n let hasPrefix = true\n if (encoded_transaction.length < prefixBytes.length) {\n hasPrefix = false\n } else {\n for (let i = 0; i < prefixBytes.length; i++) {\n if (encoded_transaction[i] !== prefixBytes[i]) {\n hasPrefix = false\n break\n }\n }\n }\n\n const decodedData = decodeMsgpack(hasPrefix ? encoded_transaction.slice(prefixBytes.length) : encoded_transaction)\n return transactionCodec.decode(decodedData, 'msgpack')\n}\n\n/**\n * Decodes a collection of MsgPack bytes into a transaction collection.\n *\n * # Parameters\n * * `encoded_transaction` - A collection of MsgPack encoded bytes, each representing a transaction.\n *\n * # Returns\n * A collection of decoded transactions or an error if decoding fails.\n */\nexport function decodeTransactions(encoded_transactions: Uint8Array[]): Transaction[] {\n return encoded_transactions.map((et) => decodeTransaction(et))\n}\n\n/**\n * Return the size of the transaction in bytes as if it was already signed and encoded.\n * This is useful for estimating the fee for the transaction.\n */\nexport function estimateTransactionSize(transaction: Transaction): bigint {\n const encoded = encodeTransactionRaw(transaction)\n return BigInt(encoded.length + SIGNATURE_ENCODING_INCR)\n}\n\n/**\n * Groups a collection of transactions by calculating and assigning the group to each transaction.\n */\nexport function groupTransactions(transactions: Transaction[]): Transaction[] {\n const group = computeGroup(transactions)\n return transactions.map(\n (tx) =>\n new Transaction({\n ...tx,\n group,\n }),\n )\n}\n\nexport function assignFee(transaction: Transaction, feeParams: FeeParams): Transaction {\n const fee = calculateFee(transaction, feeParams)\n return new Transaction({\n ...transaction,\n fee,\n })\n}\n\nfunction computeGroup(transactions: Transaction[]): Uint8Array {\n if (transactions.length === 0) {\n throw new Error('Transaction group size cannot be 0')\n }\n\n if (transactions.length > MAX_TRANSACTION_GROUP_SIZE) {\n throw new Error(`Transaction group size exceeds the max limit of ${MAX_TRANSACTION_GROUP_SIZE}`)\n }\n\n const txHashes = transactions.map((tx) => {\n if (tx.group) {\n throw new Error('Transactions must not already be grouped')\n }\n\n const encodedBytes = encodeTransaction(tx)\n return hash(encodedBytes)\n })\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_GROUP_DOMAIN_SEPARATOR)\n const encodedBytes = encodeMsgpack({\n txlist: txHashes,\n })\n\n const prefixedBytes = concatArrays(prefixBytes, encodedBytes)\n return hash(prefixedBytes)\n}\n\nexport function calculateFee(transaction: Transaction, feeParams: FeeParams): bigint {\n let calculatedFee = 0n\n\n if (feeParams.feePerByte > 0n) {\n const estimatedSize = estimateTransactionSize(transaction)\n calculatedFee = feeParams.feePerByte * BigInt(estimatedSize)\n }\n\n if (calculatedFee < feeParams.minFee) {\n calculatedFee = feeParams.minFee\n }\n\n if (feeParams.extraFee) {\n calculatedFee += feeParams.extraFee\n }\n\n if (feeParams.maxFee && calculatedFee > feeParams.maxFee) {\n throw new Error(`Transaction fee ${calculatedFee} µALGO is greater than maxFee ${feeParams.maxFee} µALGO`)\n }\n\n return calculatedFee\n}\n"],"mappings":"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"}
@@ -155,10 +155,11 @@ var Transaction = class {
155
155
  const rawTxId = this.rawTxId();
156
156
  return base32.encode(rawTxId).slice(0, TRANSACTION_ID_LENGTH);
157
157
  }
158
- static [Symbol.hasInstance](obj) {
159
- return Boolean(obj && typeof obj === "object" && TXN_SYMBOL in obj && obj[TXN_SYMBOL]);
160
- }
161
158
  };
159
+ Object.defineProperty(Transaction, Symbol.hasInstance, { value: function(obj) {
160
+ if (obj instanceof Object && Object.getPrototypeOf(obj) === Transaction.prototype) return true;
161
+ return Boolean(obj && typeof obj === "object" && TXN_SYMBOL in obj && obj[TXN_SYMBOL]);
162
+ } });
162
163
  /**
163
164
  * Codec for Transaction class.
164
165
  * Handles encoding/decoding between Transaction class instances and wire format.
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.mjs","names":[],"sources":["../../../../../packages/transact/src/transactions/transaction.ts"],"sourcesContent":["import type { EncodingFormat, WireObject } from '@algorandfoundation/algokit-common'\nimport {\n Address,\n Codec,\n MAX_TRANSACTION_GROUP_SIZE,\n SIGNATURE_ENCODING_INCR,\n TRANSACTION_DOMAIN_SEPARATOR,\n TRANSACTION_GROUP_DOMAIN_SEPARATOR,\n TRANSACTION_ID_LENGTH,\n concatArrays,\n decodeMsgpack,\n encodeMsgpack,\n hash,\n} from '@algorandfoundation/algokit-common'\nimport base32 from 'hi-base32'\nimport { AppCallTransactionFields, validateAppCallTransaction } from './app-call'\nimport { AssetConfigTransactionFields, validateAssetConfigTransaction } from './asset-config'\nimport { AssetFreezeTransactionFields, validateAssetFreezeTransaction } from './asset-freeze'\nimport { AssetTransferTransactionFields, validateAssetTransferTransaction } from './asset-transfer'\nimport { TransactionValidationError, getValidationErrorMessage } from './common'\nimport { HeartbeatTransactionFields } from './heartbeat'\nimport { KeyRegistrationTransactionFields, validateKeyRegistrationTransaction } from './key-registration'\nimport { PaymentTransactionFields } from './payment'\nimport { StateProofTransactionFields } from './state-proof'\nimport { transactionParamsCodec } from './transaction-meta'\nimport { TransactionType } from './transaction-type'\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nexport const TXN_SYMBOL = Symbol.for('algokit_transact:Transaction')\n\n/**\n * Represents the parameters for a complete Algorand transaction.\n *\n * This structure contains the fields that are present in every transaction,\n * regardless of transaction type, plus transaction-type-specific fields.\n */\nexport type TransactionParams = {\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n}\n\n/**\n * Represents a complete Algorand transaction.\n */\nexport class Transaction implements TransactionParams {\n /** @internal */\n [TXN_SYMBOL]: boolean\n\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n\n constructor(params: TransactionParams) {\n this[TXN_SYMBOL] = true\n this.type = params.type\n this.sender = params.sender\n this.fee = params.fee\n this.firstValid = params.firstValid\n this.lastValid = params.lastValid\n this.genesisHash = params.genesisHash\n this.genesisId = params.genesisId\n this.note = params.note\n this.rekeyTo = params.rekeyTo\n this.lease = params.lease\n this.group = params.group\n this.payment = params.payment\n this.assetTransfer = params.assetTransfer\n this.assetConfig = params.assetConfig\n this.appCall = params.appCall\n this.keyRegistration = params.keyRegistration\n this.assetFreeze = params.assetFreeze\n this.heartbeat = params.heartbeat\n this.stateProof = params.stateProof\n }\n\n private rawTxId(): Uint8Array {\n if (this.genesisHash === undefined) {\n throw new Error('Cannot compute transaction id without genesis hash')\n }\n\n const encodedBytes = encodeTransaction(this)\n return hash(encodedBytes)\n }\n\n /**\n * Get the transaction ID as a base32-encoded string.\n */\n txId(): string {\n const rawTxId = this.rawTxId()\n\n return base32.encode(rawTxId).slice(0, TRANSACTION_ID_LENGTH)\n }\n\n static [Symbol.hasInstance](obj: unknown) {\n return Boolean(obj && typeof obj === 'object' && TXN_SYMBOL in obj && obj[TXN_SYMBOL as keyof typeof obj])\n }\n}\n\n/**\n * Codec for Transaction class.\n * Handles encoding/decoding between Transaction class instances and wire format.\n */\nclass TransactionCodec extends Codec<Transaction, Record<string, unknown>, WireObject> {\n public defaultValue(): Transaction {\n return new Transaction({\n type: TransactionType.Unknown,\n sender: Address.zeroAddress(),\n firstValid: 0n,\n lastValid: 0n,\n })\n }\n\n protected toEncoded(value: Transaction, format: EncodingFormat): Record<string, unknown> {\n return transactionParamsCodec.encode({ ...value }, format)\n }\n\n protected fromEncoded(value: WireObject, format: EncodingFormat): Transaction {\n const params = transactionParamsCodec.decode(value, format)\n return new Transaction(params)\n }\n\n public isDefaultValue(_: Transaction): boolean {\n return false\n }\n}\n\nexport const transactionCodec = new TransactionCodec()\n\nexport type FeeParams = {\n feePerByte: bigint\n minFee: bigint\n extraFee?: bigint\n maxFee?: bigint\n}\n\n/**\n * Get the transaction type from the encoded transaction.\n * This is particularly useful when decoding a transaction that has an unknown type\n */\nexport function getEncodedTransactionType(encoded_transaction: Uint8Array): TransactionType {\n const decoded = decodeTransaction(encoded_transaction)\n return decoded.type\n}\n\n/**\n * Encode the transaction with the domain separation (e.g. \"TX\") prefix\n *\n * @param transaction - The transaction to encode\n * @returns The MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransaction(transaction: Transaction): Uint8Array {\n const rawBytes = encodeTransactionRaw(transaction)\n\n // Add domain separation prefix\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n return concatArrays(prefixBytes, rawBytes)\n}\n\n/**\n * Encode transactions with the domain separation (e.g. \"TX\") prefix\n *\n * @param transactions - A collection of transactions to encode\n * @returns A collection of MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransactions(transactions: Transaction[]): Uint8Array[] {\n return transactions.map((tx) => encodeTransaction(tx))\n}\n\n/**\n * Validate a transaction\n */\nexport function validateTransaction(transaction: Transaction): void {\n // Validate that only one transaction type specific field is set\n const typeFields = [\n transaction.payment,\n transaction.assetTransfer,\n transaction.assetConfig,\n transaction.appCall,\n transaction.keyRegistration,\n transaction.assetFreeze,\n transaction.heartbeat,\n transaction.stateProof,\n ]\n\n const setFieldsCount = typeFields.filter((field) => field !== undefined).length\n\n if (setFieldsCount > 1) {\n throw new Error('Multiple transaction type specific fields set')\n }\n\n // Perform type-specific validation where applicable\n let typeName = 'Transaction'\n const errors = new Array<TransactionValidationError>()\n if (transaction.assetTransfer) {\n typeName = 'Asset transfer'\n errors.push(...validateAssetTransferTransaction(transaction.assetTransfer))\n } else if (transaction.assetConfig) {\n typeName = 'Asset config'\n errors.push(...validateAssetConfigTransaction(transaction.assetConfig))\n } else if (transaction.appCall) {\n typeName = 'App call'\n errors.push(...validateAppCallTransaction(transaction.appCall))\n } else if (transaction.keyRegistration) {\n typeName = 'Key registration'\n errors.push(...validateKeyRegistrationTransaction(transaction.keyRegistration))\n } else if (transaction.assetFreeze) {\n typeName = 'Asset freeze'\n errors.push(...validateAssetFreezeTransaction(transaction.assetFreeze))\n }\n\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => getValidationErrorMessage(e))\n throw new Error(`${typeName} validation failed: ${errorMessages.join('\\n')}`)\n }\n}\n\n/**\n * Encode the transaction without the domain separation (e.g. \"TX\") prefix\n * This is useful for encoding the transaction for signing with tools that automatically add \"TX\" prefix to the transaction bytes.\n */\nexport function encodeTransactionRaw(transaction: Transaction): Uint8Array {\n const encodingData = transactionCodec.encode(transaction, 'msgpack')\n return encodeMsgpack(encodingData)\n}\n\n/**\n * Decodes MsgPack bytes into a transaction.\n *\n * # Parameters\n * * `encoded_transaction` - MsgPack encoded bytes representing a transaction.\n *\n * # Returns\n * A decoded transaction or an error if decoding fails.\n */\nexport function decodeTransaction(encoded_transaction: Uint8Array): Transaction {\n if (encoded_transaction.length === 0) {\n throw new Error('attempted to decode 0 bytes')\n }\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n // Check if the transaction has the domain separation prefix\n let hasPrefix = true\n if (encoded_transaction.length < prefixBytes.length) {\n hasPrefix = false\n } else {\n for (let i = 0; i < prefixBytes.length; i++) {\n if (encoded_transaction[i] !== prefixBytes[i]) {\n hasPrefix = false\n break\n }\n }\n }\n\n const decodedData = decodeMsgpack(hasPrefix ? encoded_transaction.slice(prefixBytes.length) : encoded_transaction)\n return transactionCodec.decode(decodedData, 'msgpack')\n}\n\n/**\n * Decodes a collection of MsgPack bytes into a transaction collection.\n *\n * # Parameters\n * * `encoded_transaction` - A collection of MsgPack encoded bytes, each representing a transaction.\n *\n * # Returns\n * A collection of decoded transactions or an error if decoding fails.\n */\nexport function decodeTransactions(encoded_transactions: Uint8Array[]): Transaction[] {\n return encoded_transactions.map((et) => decodeTransaction(et))\n}\n\n/**\n * Return the size of the transaction in bytes as if it was already signed and encoded.\n * This is useful for estimating the fee for the transaction.\n */\nexport function estimateTransactionSize(transaction: Transaction): bigint {\n const encoded = encodeTransactionRaw(transaction)\n return BigInt(encoded.length + SIGNATURE_ENCODING_INCR)\n}\n\n/**\n * Groups a collection of transactions by calculating and assigning the group to each transaction.\n */\nexport function groupTransactions(transactions: Transaction[]): Transaction[] {\n const group = computeGroup(transactions)\n return transactions.map(\n (tx) =>\n new Transaction({\n ...tx,\n group,\n }),\n )\n}\n\nexport function assignFee(transaction: Transaction, feeParams: FeeParams): Transaction {\n const fee = calculateFee(transaction, feeParams)\n return new Transaction({\n ...transaction,\n fee,\n })\n}\n\nfunction computeGroup(transactions: Transaction[]): Uint8Array {\n if (transactions.length === 0) {\n throw new Error('Transaction group size cannot be 0')\n }\n\n if (transactions.length > MAX_TRANSACTION_GROUP_SIZE) {\n throw new Error(`Transaction group size exceeds the max limit of ${MAX_TRANSACTION_GROUP_SIZE}`)\n }\n\n const txHashes = transactions.map((tx) => {\n if (tx.group) {\n throw new Error('Transactions must not already be grouped')\n }\n\n const encodedBytes = encodeTransaction(tx)\n return hash(encodedBytes)\n })\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_GROUP_DOMAIN_SEPARATOR)\n const encodedBytes = encodeMsgpack({\n txlist: txHashes,\n })\n\n const prefixedBytes = concatArrays(prefixBytes, encodedBytes)\n return hash(prefixedBytes)\n}\n\nexport function calculateFee(transaction: Transaction, feeParams: FeeParams): bigint {\n let calculatedFee = 0n\n\n if (feeParams.feePerByte > 0n) {\n const estimatedSize = estimateTransactionSize(transaction)\n calculatedFee = feeParams.feePerByte * BigInt(estimatedSize)\n }\n\n if (calculatedFee < feeParams.minFee) {\n calculatedFee = feeParams.minFee\n }\n\n if (feeParams.extraFee) {\n calculatedFee += feeParams.extraFee\n }\n\n if (feeParams.maxFee && calculatedFee > feeParams.maxFee) {\n throw new Error(`Transaction fee ${calculatedFee} µALGO is greater than maxFee ${feeParams.maxFee} µALGO`)\n }\n\n return calculatedFee\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA4BA,MAAa,aAAa,OAAO,IAAI,+BAA+B;;;;AAmIpE,IAAa,cAAb,MAAsD;;CAEpD,CAAC;;;;CAKD;;;;;;CAOA;;;;;;CAOA;;;;CAKA;;;;;;CAOA;;;;;;CAOA;;;;;;CAOA;;;;;;CAOA;;;;;;;;CASA;;;;;;;;;CAUA;;;;;;CAOA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;CAEA,YAAY,QAA2B;AACrC,OAAK,cAAc;AACnB,OAAK,OAAO,OAAO;AACnB,OAAK,SAAS,OAAO;AACrB,OAAK,MAAM,OAAO;AAClB,OAAK,aAAa,OAAO;AACzB,OAAK,YAAY,OAAO;AACxB,OAAK,cAAc,OAAO;AAC1B,OAAK,YAAY,OAAO;AACxB,OAAK,OAAO,OAAO;AACnB,OAAK,UAAU,OAAO;AACtB,OAAK,QAAQ,OAAO;AACpB,OAAK,QAAQ,OAAO;AACpB,OAAK,UAAU,OAAO;AACtB,OAAK,gBAAgB,OAAO;AAC5B,OAAK,cAAc,OAAO;AAC1B,OAAK,UAAU,OAAO;AACtB,OAAK,kBAAkB,OAAO;AAC9B,OAAK,cAAc,OAAO;AAC1B,OAAK,YAAY,OAAO;AACxB,OAAK,aAAa,OAAO;;CAG3B,AAAQ,UAAsB;AAC5B,MAAI,KAAK,gBAAgB,OACvB,OAAM,IAAI,MAAM,qDAAqD;AAIvE,SAAO,KADc,kBAAkB,KAAK,CACnB;;;;;CAM3B,OAAe;EACb,MAAM,UAAU,KAAK,SAAS;AAE9B,SAAO,OAAO,OAAO,QAAQ,CAAC,MAAM,GAAG,sBAAsB;;CAG/D,QAAQ,OAAO,aAAa,KAAc;AACxC,SAAO,QAAQ,OAAO,OAAO,QAAQ,YAAY,cAAc,OAAO,IAAI,YAAgC;;;;;;;AAQ9G,IAAM,mBAAN,cAA+B,MAAwD;CACrF,AAAO,eAA4B;AACjC,SAAO,IAAI,YAAY;GACrB,MAAM,gBAAgB;GACtB,QAAQ,QAAQ,aAAa;GAC7B,YAAY;GACZ,WAAW;GACZ,CAAC;;CAGJ,AAAU,UAAU,OAAoB,QAAiD;AACvF,SAAO,uBAAuB,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO;;CAG5D,AAAU,YAAY,OAAmB,QAAqC;AAE5E,SAAO,IAAI,YADI,uBAAuB,OAAO,OAAO,OAAO,CAC7B;;CAGhC,AAAO,eAAe,GAAyB;AAC7C,SAAO;;;AAIX,MAAa,mBAAmB,IAAI,kBAAkB;;;;;AAatD,SAAgB,0BAA0B,qBAAkD;AAE1F,QADgB,kBAAkB,oBAAoB,CACvC;;;;;;;;AASjB,SAAgB,kBAAkB,aAAsC;CACtE,MAAM,WAAW,qBAAqB,YAAY;AAIlD,QAAO,aADa,IAAI,aAAa,CAAC,OAAO,6BAA6B,EACzC,SAAS;;;;;;;;AAS5C,SAAgB,mBAAmB,cAA2C;AAC5E,QAAO,aAAa,KAAK,OAAO,kBAAkB,GAAG,CAAC;;;;;AAMxD,SAAgB,oBAAoB,aAAgC;AAelE,KAbmB;EACjB,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACb,CAEiC,QAAQ,UAAU,UAAU,OAAU,CAAC,SAEpD,EACnB,OAAM,IAAI,MAAM,gDAAgD;CAIlE,IAAI,WAAW;CACf,MAAM,SAAS,IAAI,OAAmC;AACtD,KAAI,YAAY,eAAe;AAC7B,aAAW;AACX,SAAO,KAAK,GAAG,iCAAiC,YAAY,cAAc,CAAC;YAClE,YAAY,aAAa;AAClC,aAAW;AACX,SAAO,KAAK,GAAG,+BAA+B,YAAY,YAAY,CAAC;YAC9D,YAAY,SAAS;AAC9B,aAAW;AACX,SAAO,KAAK,GAAG,2BAA2B,YAAY,QAAQ,CAAC;YACtD,YAAY,iBAAiB;AACtC,aAAW;AACX,SAAO,KAAK,GAAG,mCAAmC,YAAY,gBAAgB,CAAC;YACtE,YAAY,aAAa;AAClC,aAAW;AACX,SAAO,KAAK,GAAG,+BAA+B,YAAY,YAAY,CAAC;;AAGzE,KAAI,OAAO,SAAS,GAAG;EACrB,MAAM,gBAAgB,OAAO,KAAK,MAAM,0BAA0B,EAAE,CAAC;AACrE,QAAM,IAAI,MAAM,GAAG,SAAS,sBAAsB,cAAc,KAAK,KAAK,GAAG;;;;;;;AAQjF,SAAgB,qBAAqB,aAAsC;AAEzE,QAAO,cADc,iBAAiB,OAAO,aAAa,UAAU,CAClC;;;;;;;;;;;AAYpC,SAAgB,kBAAkB,qBAA8C;AAC9E,KAAI,oBAAoB,WAAW,EACjC,OAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,cAAc,IAAI,aAAa,CAAC,OAAO,6BAA6B;CAE1E,IAAI,YAAY;AAChB,KAAI,oBAAoB,SAAS,YAAY,OAC3C,aAAY;KAEZ,MAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,IACtC,KAAI,oBAAoB,OAAO,YAAY,IAAI;AAC7C,cAAY;AACZ;;CAKN,MAAM,cAAc,cAAc,YAAY,oBAAoB,MAAM,YAAY,OAAO,GAAG,oBAAoB;AAClH,QAAO,iBAAiB,OAAO,aAAa,UAAU;;;;;;;;;;;AAYxD,SAAgB,mBAAmB,sBAAmD;AACpF,QAAO,qBAAqB,KAAK,OAAO,kBAAkB,GAAG,CAAC;;;;;;AAOhE,SAAgB,wBAAwB,aAAkC;CACxE,MAAM,UAAU,qBAAqB,YAAY;AACjD,QAAO,OAAO,QAAQ,SAAS,wBAAwB;;;;;AAMzD,SAAgB,kBAAkB,cAA4C;CAC5E,MAAM,QAAQ,aAAa,aAAa;AACxC,QAAO,aAAa,KACjB,OACC,IAAI,YAAY;EACd,GAAG;EACH;EACD,CAAC,CACL;;AAGH,SAAgB,UAAU,aAA0B,WAAmC;CACrF,MAAM,MAAM,aAAa,aAAa,UAAU;AAChD,QAAO,IAAI,YAAY;EACrB,GAAG;EACH;EACD,CAAC;;AAGJ,SAAS,aAAa,cAAyC;AAC7D,KAAI,aAAa,WAAW,EAC1B,OAAM,IAAI,MAAM,qCAAqC;AAGvD,KAAI,aAAa,SAAS,2BACxB,OAAM,IAAI,MAAM,mDAAmD,6BAA6B;CAGlG,MAAM,WAAW,aAAa,KAAK,OAAO;AACxC,MAAI,GAAG,MACL,OAAM,IAAI,MAAM,2CAA2C;AAI7D,SAAO,KADc,kBAAkB,GAAG,CACjB;GACzB;AAQF,QAAO,KADe,aALF,IAAI,aAAa,CAAC,OAAO,mCAAmC,EAC3D,cAAc,EACjC,QAAQ,UACT,CAAC,CAE2D,CACnC;;AAG5B,SAAgB,aAAa,aAA0B,WAA8B;CACnF,IAAI,gBAAgB;AAEpB,KAAI,UAAU,aAAa,IAAI;EAC7B,MAAM,gBAAgB,wBAAwB,YAAY;AAC1D,kBAAgB,UAAU,aAAa,OAAO,cAAc;;AAG9D,KAAI,gBAAgB,UAAU,OAC5B,iBAAgB,UAAU;AAG5B,KAAI,UAAU,SACZ,kBAAiB,UAAU;AAG7B,KAAI,UAAU,UAAU,gBAAgB,UAAU,OAChD,OAAM,IAAI,MAAM,mBAAmB,cAAc,gCAAgC,UAAU,OAAO,QAAQ;AAG5G,QAAO"}
1
+ {"version":3,"file":"transaction.mjs","names":[],"sources":["../../../../../packages/transact/src/transactions/transaction.ts"],"sourcesContent":["import type { EncodingFormat, WireObject } from '@algorandfoundation/algokit-common'\nimport {\n Address,\n Codec,\n MAX_TRANSACTION_GROUP_SIZE,\n SIGNATURE_ENCODING_INCR,\n TRANSACTION_DOMAIN_SEPARATOR,\n TRANSACTION_GROUP_DOMAIN_SEPARATOR,\n TRANSACTION_ID_LENGTH,\n concatArrays,\n decodeMsgpack,\n encodeMsgpack,\n hash,\n} from '@algorandfoundation/algokit-common'\nimport base32 from 'hi-base32'\nimport { AppCallTransactionFields, validateAppCallTransaction } from './app-call'\nimport { AssetConfigTransactionFields, validateAssetConfigTransaction } from './asset-config'\nimport { AssetFreezeTransactionFields, validateAssetFreezeTransaction } from './asset-freeze'\nimport { AssetTransferTransactionFields, validateAssetTransferTransaction } from './asset-transfer'\nimport { TransactionValidationError, getValidationErrorMessage } from './common'\nimport { HeartbeatTransactionFields } from './heartbeat'\nimport { KeyRegistrationTransactionFields, validateKeyRegistrationTransaction } from './key-registration'\nimport { PaymentTransactionFields } from './payment'\nimport { StateProofTransactionFields } from './state-proof'\nimport { transactionParamsCodec } from './transaction-meta'\nimport { TransactionType } from './transaction-type'\n\n/** Symbol used for instanceof checks across packages (CJS/ESM) */\nexport const TXN_SYMBOL = Symbol.for('algokit_transact:Transaction')\n\n/**\n * Represents the parameters for a complete Algorand transaction.\n *\n * This structure contains the fields that are present in every transaction,\n * regardless of transaction type, plus transaction-type-specific fields.\n */\nexport type TransactionParams = {\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n}\n\n/**\n * Represents a complete Algorand transaction.\n */\nexport class Transaction implements TransactionParams {\n /** @internal */\n [TXN_SYMBOL]: boolean\n\n /**\n * The type of transaction\n */\n type: TransactionType\n\n /**\n * The account that authorized the transaction.\n *\n * Fees are deducted from this account.\n */\n sender: Address\n\n /**\n * Optional transaction fee in microALGO.\n *\n * When not set, the fee will be interpreted as 0 by the network.\n */\n fee?: bigint\n\n /**\n * First round for when the transaction is valid.\n */\n firstValid: bigint\n\n /**\n * Last round for when the transaction is valid.\n *\n * After this round, the transaction will be expired.\n */\n lastValid: bigint\n\n /**\n * Hash of the genesis block of the network.\n *\n * Used to identify which network the transaction is for.\n */\n genesisHash?: Uint8Array\n\n /**\n * Genesis ID of the network.\n *\n * A human-readable string used alongside genesis hash to identify the network.\n */\n genesisId?: string\n\n /**\n * Optional user-defined note field.\n *\n * Can contain arbitrary data up to 1KB in size.\n */\n note?: Uint8Array\n\n /**\n * Optional authorized account for future transactions.\n *\n * If set, only this account will be used for transaction authorization going forward.\n * Reverting back control to the original address must be done by setting this field to\n * the original address.\n */\n rekeyTo?: Address\n\n /**\n * Optional lease value to enforce mutual transaction exclusion.\n *\n * When a transaction with a non-empty lease field is confirmed, the lease is acquired.\n * A lease X is acquired by the sender, generating the (sender, X) lease.\n * The lease is kept active until the last_valid round of the transaction has elapsed.\n * No other transaction sent by the same sender can be confirmed until the lease expires.\n */\n lease?: Uint8Array\n\n /**\n * Optional group ID for atomic transaction grouping.\n *\n * Transactions with the same group ID must execute together or not at all.\n */\n group?: Uint8Array\n\n /**\n * Payment specific fields\n */\n payment?: PaymentTransactionFields\n\n /**\n * Asset transfer specific fields\n */\n assetTransfer?: AssetTransferTransactionFields\n\n /**\n * Asset config specific fields\n */\n assetConfig?: AssetConfigTransactionFields\n\n /**\n * App call specific fields\n */\n appCall?: AppCallTransactionFields\n\n /**\n * Key registration specific fields\n */\n keyRegistration?: KeyRegistrationTransactionFields\n\n /**\n * Asset freeze specific fields\n */\n assetFreeze?: AssetFreezeTransactionFields\n\n /**\n * Heartbeat specific fields\n */\n heartbeat?: HeartbeatTransactionFields\n\n /**\n * State proof specific fields\n */\n stateProof?: StateProofTransactionFields\n\n constructor(params: TransactionParams) {\n this[TXN_SYMBOL] = true\n this.type = params.type\n this.sender = params.sender\n this.fee = params.fee\n this.firstValid = params.firstValid\n this.lastValid = params.lastValid\n this.genesisHash = params.genesisHash\n this.genesisId = params.genesisId\n this.note = params.note\n this.rekeyTo = params.rekeyTo\n this.lease = params.lease\n this.group = params.group\n this.payment = params.payment\n this.assetTransfer = params.assetTransfer\n this.assetConfig = params.assetConfig\n this.appCall = params.appCall\n this.keyRegistration = params.keyRegistration\n this.assetFreeze = params.assetFreeze\n this.heartbeat = params.heartbeat\n this.stateProof = params.stateProof\n }\n\n private rawTxId(): Uint8Array {\n if (this.genesisHash === undefined) {\n throw new Error('Cannot compute transaction id without genesis hash')\n }\n\n const encodedBytes = encodeTransaction(this)\n return hash(encodedBytes)\n }\n\n /**\n * Get the transaction ID as a base32-encoded string.\n */\n txId(): string {\n const rawTxId = this.rawTxId()\n\n return base32.encode(rawTxId).slice(0, TRANSACTION_ID_LENGTH)\n }\n}\n\n// Define Symbol.hasInstance outside the class to avoid Metro/Hermes parser issues\n// with static computed property names like `static [Symbol.hasInstance]()`\n// Also must handle Babel's _classCallCheck which uses instanceof before TXN_SYMBOL is set\nObject.defineProperty(Transaction, Symbol.hasInstance, {\n value: function (obj: unknown): boolean {\n // First check prototype chain (handles Babel's _classCallCheck and normal instances)\n if (obj instanceof Object && Object.getPrototypeOf(obj) === Transaction.prototype) {\n return true\n }\n // Then check for the brand symbol (handles cross-realm/serialized instances)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return Boolean(obj && typeof obj === 'object' && TXN_SYMBOL in obj && (obj as any)[TXN_SYMBOL])\n },\n})\n\n/**\n * Codec for Transaction class.\n * Handles encoding/decoding between Transaction class instances and wire format.\n */\nclass TransactionCodec extends Codec<Transaction, Record<string, unknown>, WireObject> {\n public defaultValue(): Transaction {\n return new Transaction({\n type: TransactionType.Unknown,\n sender: Address.zeroAddress(),\n firstValid: 0n,\n lastValid: 0n,\n })\n }\n\n protected toEncoded(value: Transaction, format: EncodingFormat): Record<string, unknown> {\n return transactionParamsCodec.encode({ ...value }, format)\n }\n\n protected fromEncoded(value: WireObject, format: EncodingFormat): Transaction {\n const params = transactionParamsCodec.decode(value, format)\n return new Transaction(params)\n }\n\n public isDefaultValue(_: Transaction): boolean {\n return false\n }\n}\n\nexport const transactionCodec = new TransactionCodec()\n\nexport type FeeParams = {\n feePerByte: bigint\n minFee: bigint\n extraFee?: bigint\n maxFee?: bigint\n}\n\n/**\n * Get the transaction type from the encoded transaction.\n * This is particularly useful when decoding a transaction that has an unknown type\n */\nexport function getEncodedTransactionType(encoded_transaction: Uint8Array): TransactionType {\n const decoded = decodeTransaction(encoded_transaction)\n return decoded.type\n}\n\n/**\n * Encode the transaction with the domain separation (e.g. \"TX\") prefix\n *\n * @param transaction - The transaction to encode\n * @returns The MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransaction(transaction: Transaction): Uint8Array {\n const rawBytes = encodeTransactionRaw(transaction)\n\n // Add domain separation prefix\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n return concatArrays(prefixBytes, rawBytes)\n}\n\n/**\n * Encode transactions with the domain separation (e.g. \"TX\") prefix\n *\n * @param transactions - A collection of transactions to encode\n * @returns A collection of MsgPack encoded bytes or an error if encoding fails.\n */\nexport function encodeTransactions(transactions: Transaction[]): Uint8Array[] {\n return transactions.map((tx) => encodeTransaction(tx))\n}\n\n/**\n * Validate a transaction\n */\nexport function validateTransaction(transaction: Transaction): void {\n // Validate that only one transaction type specific field is set\n const typeFields = [\n transaction.payment,\n transaction.assetTransfer,\n transaction.assetConfig,\n transaction.appCall,\n transaction.keyRegistration,\n transaction.assetFreeze,\n transaction.heartbeat,\n transaction.stateProof,\n ]\n\n const setFieldsCount = typeFields.filter((field) => field !== undefined).length\n\n if (setFieldsCount > 1) {\n throw new Error('Multiple transaction type specific fields set')\n }\n\n // Perform type-specific validation where applicable\n let typeName = 'Transaction'\n const errors = new Array<TransactionValidationError>()\n if (transaction.assetTransfer) {\n typeName = 'Asset transfer'\n errors.push(...validateAssetTransferTransaction(transaction.assetTransfer))\n } else if (transaction.assetConfig) {\n typeName = 'Asset config'\n errors.push(...validateAssetConfigTransaction(transaction.assetConfig))\n } else if (transaction.appCall) {\n typeName = 'App call'\n errors.push(...validateAppCallTransaction(transaction.appCall))\n } else if (transaction.keyRegistration) {\n typeName = 'Key registration'\n errors.push(...validateKeyRegistrationTransaction(transaction.keyRegistration))\n } else if (transaction.assetFreeze) {\n typeName = 'Asset freeze'\n errors.push(...validateAssetFreezeTransaction(transaction.assetFreeze))\n }\n\n if (errors.length > 0) {\n const errorMessages = errors.map((e) => getValidationErrorMessage(e))\n throw new Error(`${typeName} validation failed: ${errorMessages.join('\\n')}`)\n }\n}\n\n/**\n * Encode the transaction without the domain separation (e.g. \"TX\") prefix\n * This is useful for encoding the transaction for signing with tools that automatically add \"TX\" prefix to the transaction bytes.\n */\nexport function encodeTransactionRaw(transaction: Transaction): Uint8Array {\n const encodingData = transactionCodec.encode(transaction, 'msgpack')\n return encodeMsgpack(encodingData)\n}\n\n/**\n * Decodes MsgPack bytes into a transaction.\n *\n * # Parameters\n * * `encoded_transaction` - MsgPack encoded bytes representing a transaction.\n *\n * # Returns\n * A decoded transaction or an error if decoding fails.\n */\nexport function decodeTransaction(encoded_transaction: Uint8Array): Transaction {\n if (encoded_transaction.length === 0) {\n throw new Error('attempted to decode 0 bytes')\n }\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_DOMAIN_SEPARATOR)\n // Check if the transaction has the domain separation prefix\n let hasPrefix = true\n if (encoded_transaction.length < prefixBytes.length) {\n hasPrefix = false\n } else {\n for (let i = 0; i < prefixBytes.length; i++) {\n if (encoded_transaction[i] !== prefixBytes[i]) {\n hasPrefix = false\n break\n }\n }\n }\n\n const decodedData = decodeMsgpack(hasPrefix ? encoded_transaction.slice(prefixBytes.length) : encoded_transaction)\n return transactionCodec.decode(decodedData, 'msgpack')\n}\n\n/**\n * Decodes a collection of MsgPack bytes into a transaction collection.\n *\n * # Parameters\n * * `encoded_transaction` - A collection of MsgPack encoded bytes, each representing a transaction.\n *\n * # Returns\n * A collection of decoded transactions or an error if decoding fails.\n */\nexport function decodeTransactions(encoded_transactions: Uint8Array[]): Transaction[] {\n return encoded_transactions.map((et) => decodeTransaction(et))\n}\n\n/**\n * Return the size of the transaction in bytes as if it was already signed and encoded.\n * This is useful for estimating the fee for the transaction.\n */\nexport function estimateTransactionSize(transaction: Transaction): bigint {\n const encoded = encodeTransactionRaw(transaction)\n return BigInt(encoded.length + SIGNATURE_ENCODING_INCR)\n}\n\n/**\n * Groups a collection of transactions by calculating and assigning the group to each transaction.\n */\nexport function groupTransactions(transactions: Transaction[]): Transaction[] {\n const group = computeGroup(transactions)\n return transactions.map(\n (tx) =>\n new Transaction({\n ...tx,\n group,\n }),\n )\n}\n\nexport function assignFee(transaction: Transaction, feeParams: FeeParams): Transaction {\n const fee = calculateFee(transaction, feeParams)\n return new Transaction({\n ...transaction,\n fee,\n })\n}\n\nfunction computeGroup(transactions: Transaction[]): Uint8Array {\n if (transactions.length === 0) {\n throw new Error('Transaction group size cannot be 0')\n }\n\n if (transactions.length > MAX_TRANSACTION_GROUP_SIZE) {\n throw new Error(`Transaction group size exceeds the max limit of ${MAX_TRANSACTION_GROUP_SIZE}`)\n }\n\n const txHashes = transactions.map((tx) => {\n if (tx.group) {\n throw new Error('Transactions must not already be grouped')\n }\n\n const encodedBytes = encodeTransaction(tx)\n return hash(encodedBytes)\n })\n\n const prefixBytes = new TextEncoder().encode(TRANSACTION_GROUP_DOMAIN_SEPARATOR)\n const encodedBytes = encodeMsgpack({\n txlist: txHashes,\n })\n\n const prefixedBytes = concatArrays(prefixBytes, encodedBytes)\n return hash(prefixedBytes)\n}\n\nexport function calculateFee(transaction: Transaction, feeParams: FeeParams): bigint {\n let calculatedFee = 0n\n\n if (feeParams.feePerByte > 0n) {\n const estimatedSize = estimateTransactionSize(transaction)\n calculatedFee = feeParams.feePerByte * BigInt(estimatedSize)\n }\n\n if (calculatedFee < feeParams.minFee) {\n calculatedFee = feeParams.minFee\n }\n\n if (feeParams.extraFee) {\n calculatedFee += feeParams.extraFee\n }\n\n if (feeParams.maxFee && calculatedFee > feeParams.maxFee) {\n throw new Error(`Transaction fee ${calculatedFee} µALGO is greater than maxFee ${feeParams.maxFee} µALGO`)\n }\n\n return calculatedFee\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AA4BA,MAAa,aAAa,OAAO,IAAI,+BAA+B;;;;AAmIpE,IAAa,cAAb,MAAsD;;CAEpD,CAAC;;;;CAKD;;;;;;CAOA;;;;;;CAOA;;;;CAKA;;;;;;CAOA;;;;;;CAOA;;;;;;CAOA;;;;;;CAOA;;;;;;;;CASA;;;;;;;;;CAUA;;;;;;CAOA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;;;;CAKA;CAEA,YAAY,QAA2B;AACrC,OAAK,cAAc;AACnB,OAAK,OAAO,OAAO;AACnB,OAAK,SAAS,OAAO;AACrB,OAAK,MAAM,OAAO;AAClB,OAAK,aAAa,OAAO;AACzB,OAAK,YAAY,OAAO;AACxB,OAAK,cAAc,OAAO;AAC1B,OAAK,YAAY,OAAO;AACxB,OAAK,OAAO,OAAO;AACnB,OAAK,UAAU,OAAO;AACtB,OAAK,QAAQ,OAAO;AACpB,OAAK,QAAQ,OAAO;AACpB,OAAK,UAAU,OAAO;AACtB,OAAK,gBAAgB,OAAO;AAC5B,OAAK,cAAc,OAAO;AAC1B,OAAK,UAAU,OAAO;AACtB,OAAK,kBAAkB,OAAO;AAC9B,OAAK,cAAc,OAAO;AAC1B,OAAK,YAAY,OAAO;AACxB,OAAK,aAAa,OAAO;;CAG3B,AAAQ,UAAsB;AAC5B,MAAI,KAAK,gBAAgB,OACvB,OAAM,IAAI,MAAM,qDAAqD;AAIvE,SAAO,KADc,kBAAkB,KAAK,CACnB;;;;;CAM3B,OAAe;EACb,MAAM,UAAU,KAAK,SAAS;AAE9B,SAAO,OAAO,OAAO,QAAQ,CAAC,MAAM,GAAG,sBAAsB;;;AAOjE,OAAO,eAAe,aAAa,OAAO,aAAa,EACrD,OAAO,SAAU,KAAuB;AAEtC,KAAI,eAAe,UAAU,OAAO,eAAe,IAAI,KAAK,YAAY,UACtE,QAAO;AAIT,QAAO,QAAQ,OAAO,OAAO,QAAQ,YAAY,cAAc,OAAQ,IAAY,YAAY;GAElG,CAAC;;;;;AAMF,IAAM,mBAAN,cAA+B,MAAwD;CACrF,AAAO,eAA4B;AACjC,SAAO,IAAI,YAAY;GACrB,MAAM,gBAAgB;GACtB,QAAQ,QAAQ,aAAa;GAC7B,YAAY;GACZ,WAAW;GACZ,CAAC;;CAGJ,AAAU,UAAU,OAAoB,QAAiD;AACvF,SAAO,uBAAuB,OAAO,EAAE,GAAG,OAAO,EAAE,OAAO;;CAG5D,AAAU,YAAY,OAAmB,QAAqC;AAE5E,SAAO,IAAI,YADI,uBAAuB,OAAO,OAAO,OAAO,CAC7B;;CAGhC,AAAO,eAAe,GAAyB;AAC7C,SAAO;;;AAIX,MAAa,mBAAmB,IAAI,kBAAkB;;;;;AAatD,SAAgB,0BAA0B,qBAAkD;AAE1F,QADgB,kBAAkB,oBAAoB,CACvC;;;;;;;;AASjB,SAAgB,kBAAkB,aAAsC;CACtE,MAAM,WAAW,qBAAqB,YAAY;AAIlD,QAAO,aADa,IAAI,aAAa,CAAC,OAAO,6BAA6B,EACzC,SAAS;;;;;;;;AAS5C,SAAgB,mBAAmB,cAA2C;AAC5E,QAAO,aAAa,KAAK,OAAO,kBAAkB,GAAG,CAAC;;;;;AAMxD,SAAgB,oBAAoB,aAAgC;AAelE,KAbmB;EACjB,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACZ,YAAY;EACb,CAEiC,QAAQ,UAAU,UAAU,OAAU,CAAC,SAEpD,EACnB,OAAM,IAAI,MAAM,gDAAgD;CAIlE,IAAI,WAAW;CACf,MAAM,SAAS,IAAI,OAAmC;AACtD,KAAI,YAAY,eAAe;AAC7B,aAAW;AACX,SAAO,KAAK,GAAG,iCAAiC,YAAY,cAAc,CAAC;YAClE,YAAY,aAAa;AAClC,aAAW;AACX,SAAO,KAAK,GAAG,+BAA+B,YAAY,YAAY,CAAC;YAC9D,YAAY,SAAS;AAC9B,aAAW;AACX,SAAO,KAAK,GAAG,2BAA2B,YAAY,QAAQ,CAAC;YACtD,YAAY,iBAAiB;AACtC,aAAW;AACX,SAAO,KAAK,GAAG,mCAAmC,YAAY,gBAAgB,CAAC;YACtE,YAAY,aAAa;AAClC,aAAW;AACX,SAAO,KAAK,GAAG,+BAA+B,YAAY,YAAY,CAAC;;AAGzE,KAAI,OAAO,SAAS,GAAG;EACrB,MAAM,gBAAgB,OAAO,KAAK,MAAM,0BAA0B,EAAE,CAAC;AACrE,QAAM,IAAI,MAAM,GAAG,SAAS,sBAAsB,cAAc,KAAK,KAAK,GAAG;;;;;;;AAQjF,SAAgB,qBAAqB,aAAsC;AAEzE,QAAO,cADc,iBAAiB,OAAO,aAAa,UAAU,CAClC;;;;;;;;;;;AAYpC,SAAgB,kBAAkB,qBAA8C;AAC9E,KAAI,oBAAoB,WAAW,EACjC,OAAM,IAAI,MAAM,8BAA8B;CAGhD,MAAM,cAAc,IAAI,aAAa,CAAC,OAAO,6BAA6B;CAE1E,IAAI,YAAY;AAChB,KAAI,oBAAoB,SAAS,YAAY,OAC3C,aAAY;KAEZ,MAAK,IAAI,IAAI,GAAG,IAAI,YAAY,QAAQ,IACtC,KAAI,oBAAoB,OAAO,YAAY,IAAI;AAC7C,cAAY;AACZ;;CAKN,MAAM,cAAc,cAAc,YAAY,oBAAoB,MAAM,YAAY,OAAO,GAAG,oBAAoB;AAClH,QAAO,iBAAiB,OAAO,aAAa,UAAU;;;;;;;;;;;AAYxD,SAAgB,mBAAmB,sBAAmD;AACpF,QAAO,qBAAqB,KAAK,OAAO,kBAAkB,GAAG,CAAC;;;;;;AAOhE,SAAgB,wBAAwB,aAAkC;CACxE,MAAM,UAAU,qBAAqB,YAAY;AACjD,QAAO,OAAO,QAAQ,SAAS,wBAAwB;;;;;AAMzD,SAAgB,kBAAkB,cAA4C;CAC5E,MAAM,QAAQ,aAAa,aAAa;AACxC,QAAO,aAAa,KACjB,OACC,IAAI,YAAY;EACd,GAAG;EACH;EACD,CAAC,CACL;;AAGH,SAAgB,UAAU,aAA0B,WAAmC;CACrF,MAAM,MAAM,aAAa,aAAa,UAAU;AAChD,QAAO,IAAI,YAAY;EACrB,GAAG;EACH;EACD,CAAC;;AAGJ,SAAS,aAAa,cAAyC;AAC7D,KAAI,aAAa,WAAW,EAC1B,OAAM,IAAI,MAAM,qCAAqC;AAGvD,KAAI,aAAa,SAAS,2BACxB,OAAM,IAAI,MAAM,mDAAmD,6BAA6B;CAGlG,MAAM,WAAW,aAAa,KAAK,OAAO;AACxC,MAAI,GAAG,MACL,OAAM,IAAI,MAAM,2CAA2C;AAI7D,SAAO,KADc,kBAAkB,GAAG,CACjB;GACzB;AAQF,QAAO,KADe,aALF,IAAI,aAAa,CAAC,OAAO,mCAAmC,EAC3D,cAAc,EACjC,QAAQ,UACT,CAAC,CAE2D,CACnC;;AAG5B,SAAgB,aAAa,aAA0B,WAA8B;CACnF,IAAI,gBAAgB;AAEpB,KAAI,UAAU,aAAa,IAAI;EAC7B,MAAM,gBAAgB,wBAAwB,YAAY;AAC1D,kBAAgB,UAAU,aAAa,OAAO,cAAc;;AAG9D,KAAI,gBAAgB,UAAU,OAC5B,iBAAgB,UAAU;AAG5B,KAAI,UAAU,SACZ,kBAAiB,UAAU;AAG7B,KAAI,UAAU,UAAU,gBAAgB,UAAU,OAChD,OAAM,IAAI,MAAM,mBAAmB,cAAc,gCAAgC,UAAU,OAAO,QAAQ;AAG5G,QAAO"}
@@ -364,7 +364,7 @@ declare class AlgorandClientTransactionCreator {
364
364
  accountReferences?: ReadableAddress[] | undefined;
365
365
  appReferences?: bigint[] | undefined;
366
366
  assetReferences?: bigint[] | undefined;
367
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
367
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
368
368
  accessReferences?: ResourceReference[] | undefined;
369
369
  rejectVersion?: number | undefined;
370
370
  appId?: 0 | undefined;
@@ -433,7 +433,7 @@ declare class AlgorandClientTransactionCreator {
433
433
  accountReferences?: ReadableAddress[] | undefined;
434
434
  appReferences?: bigint[] | undefined;
435
435
  assetReferences?: bigint[] | undefined;
436
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
436
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
437
437
  accessReferences?: ResourceReference[] | undefined;
438
438
  rejectVersion?: number | undefined;
439
439
  approvalProgram: string | Uint8Array;
@@ -579,15 +579,12 @@ declare class AlgorandClientTransactionCreator {
579
579
  validityWindow?: number | bigint | undefined;
580
580
  firstValidRound?: bigint | undefined;
581
581
  lastValidRound?: bigint | undefined;
582
- approvalProgram: string | Uint8Array;
583
- clearStateProgram: string | Uint8Array;
584
582
  appId?: 0 | undefined;
585
- extraProgramPages?: number | undefined;
586
583
  onComplete?: OnApplicationComplete.NoOp | OnApplicationComplete.OptIn | OnApplicationComplete.CloseOut | OnApplicationComplete.UpdateApplication | OnApplicationComplete.DeleteApplication | undefined;
587
584
  accountReferences?: ReadableAddress[] | undefined;
588
585
  appReferences?: bigint[] | undefined;
589
586
  assetReferences?: bigint[] | undefined;
590
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
587
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
591
588
  accessReferences?: ResourceReference[] | undefined;
592
589
  rejectVersion?: number | undefined;
593
590
  schema?: {
@@ -596,8 +593,11 @@ declare class AlgorandClientTransactionCreator {
596
593
  localInts: number;
597
594
  localByteSlices: number;
598
595
  } | undefined;
596
+ extraProgramPages?: number | undefined;
597
+ approvalProgram: string | Uint8Array;
598
+ clearStateProgram: string | Uint8Array;
599
599
  method: ABIMethod;
600
- args?: (Transaction | ABIValue | Promise<Transaction> | TransactionWithSigner | AppMethodCall<{
600
+ args?: (Transaction | ABIValue | TransactionWithSigner | AppMethodCall<{
601
601
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
602
602
  sender: SendingAddress;
603
603
  rekeyTo?: ReadableAddress | undefined;
@@ -614,7 +614,7 @@ declare class AlgorandClientTransactionCreator {
614
614
  accountReferences?: ReadableAddress[] | undefined;
615
615
  appReferences?: bigint[] | undefined;
616
616
  assetReferences?: bigint[] | undefined;
617
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
617
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
618
618
  accessReferences?: ResourceReference[] | undefined;
619
619
  rejectVersion?: number | undefined;
620
620
  appId?: 0 | undefined;
@@ -627,7 +627,7 @@ declare class AlgorandClientTransactionCreator {
627
627
  localByteSlices: number;
628
628
  } | undefined;
629
629
  extraProgramPages?: number | undefined;
630
- }> | AppMethodCall<{
630
+ }> | Promise<Transaction> | AppMethodCall<{
631
631
  sender: SendingAddress;
632
632
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
633
633
  rekeyTo?: ReadableAddress | undefined;
@@ -645,7 +645,7 @@ declare class AlgorandClientTransactionCreator {
645
645
  accountReferences?: ReadableAddress[] | undefined;
646
646
  appReferences?: bigint[] | undefined;
647
647
  assetReferences?: bigint[] | undefined;
648
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
648
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
649
649
  accessReferences?: ResourceReference[] | undefined;
650
650
  rejectVersion?: number | undefined;
651
651
  approvalProgram: string | Uint8Array;
@@ -713,18 +713,18 @@ declare class AlgorandClientTransactionCreator {
713
713
  validityWindow?: number | bigint | undefined;
714
714
  firstValidRound?: bigint | undefined;
715
715
  lastValidRound?: bigint | undefined;
716
- approvalProgram: string | Uint8Array;
717
- clearStateProgram: string | Uint8Array;
718
716
  appId: bigint;
719
717
  onComplete?: OnApplicationComplete.UpdateApplication | undefined;
720
718
  accountReferences?: ReadableAddress[] | undefined;
721
719
  appReferences?: bigint[] | undefined;
722
720
  assetReferences?: bigint[] | undefined;
723
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
721
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
724
722
  accessReferences?: ResourceReference[] | undefined;
725
723
  rejectVersion?: number | undefined;
724
+ approvalProgram: string | Uint8Array;
725
+ clearStateProgram: string | Uint8Array;
726
726
  method: ABIMethod;
727
- args?: (Transaction | ABIValue | Promise<Transaction> | TransactionWithSigner | AppMethodCall<{
727
+ args?: (Transaction | ABIValue | TransactionWithSigner | AppMethodCall<{
728
728
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
729
729
  sender: SendingAddress;
730
730
  rekeyTo?: ReadableAddress | undefined;
@@ -741,7 +741,7 @@ declare class AlgorandClientTransactionCreator {
741
741
  accountReferences?: ReadableAddress[] | undefined;
742
742
  appReferences?: bigint[] | undefined;
743
743
  assetReferences?: bigint[] | undefined;
744
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
744
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
745
745
  accessReferences?: ResourceReference[] | undefined;
746
746
  rejectVersion?: number | undefined;
747
747
  appId?: 0 | undefined;
@@ -754,7 +754,7 @@ declare class AlgorandClientTransactionCreator {
754
754
  localByteSlices: number;
755
755
  } | undefined;
756
756
  extraProgramPages?: number | undefined;
757
- }> | AppMethodCall<{
757
+ }> | Promise<Transaction> | AppMethodCall<{
758
758
  sender: SendingAddress;
759
759
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
760
760
  rekeyTo?: ReadableAddress | undefined;
@@ -772,7 +772,7 @@ declare class AlgorandClientTransactionCreator {
772
772
  accountReferences?: ReadableAddress[] | undefined;
773
773
  appReferences?: bigint[] | undefined;
774
774
  assetReferences?: bigint[] | undefined;
775
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
775
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
776
776
  accessReferences?: ResourceReference[] | undefined;
777
777
  rejectVersion?: number | undefined;
778
778
  approvalProgram: string | Uint8Array;
@@ -843,11 +843,11 @@ declare class AlgorandClientTransactionCreator {
843
843
  accountReferences?: ReadableAddress[] | undefined;
844
844
  appReferences?: bigint[] | undefined;
845
845
  assetReferences?: bigint[] | undefined;
846
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
846
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
847
847
  accessReferences?: ResourceReference[] | undefined;
848
848
  rejectVersion?: number | undefined;
849
849
  method: ABIMethod;
850
- args?: (Transaction | ABIValue | Promise<Transaction> | TransactionWithSigner | AppMethodCall<{
850
+ args?: (Transaction | ABIValue | TransactionWithSigner | AppMethodCall<{
851
851
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
852
852
  sender: SendingAddress;
853
853
  rekeyTo?: ReadableAddress | undefined;
@@ -864,7 +864,7 @@ declare class AlgorandClientTransactionCreator {
864
864
  accountReferences?: ReadableAddress[] | undefined;
865
865
  appReferences?: bigint[] | undefined;
866
866
  assetReferences?: bigint[] | undefined;
867
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
867
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
868
868
  accessReferences?: ResourceReference[] | undefined;
869
869
  rejectVersion?: number | undefined;
870
870
  appId?: 0 | undefined;
@@ -877,7 +877,7 @@ declare class AlgorandClientTransactionCreator {
877
877
  localByteSlices: number;
878
878
  } | undefined;
879
879
  extraProgramPages?: number | undefined;
880
- }> | AppMethodCall<{
880
+ }> | Promise<Transaction> | AppMethodCall<{
881
881
  sender: SendingAddress;
882
882
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
883
883
  rekeyTo?: ReadableAddress | undefined;
@@ -895,7 +895,7 @@ declare class AlgorandClientTransactionCreator {
895
895
  accountReferences?: ReadableAddress[] | undefined;
896
896
  appReferences?: bigint[] | undefined;
897
897
  assetReferences?: bigint[] | undefined;
898
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
898
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
899
899
  accessReferences?: ResourceReference[] | undefined;
900
900
  rejectVersion?: number | undefined;
901
901
  approvalProgram: string | Uint8Array;
@@ -966,11 +966,11 @@ declare class AlgorandClientTransactionCreator {
966
966
  accountReferences?: ReadableAddress[] | undefined;
967
967
  appReferences?: bigint[] | undefined;
968
968
  assetReferences?: bigint[] | undefined;
969
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
969
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
970
970
  accessReferences?: ResourceReference[] | undefined;
971
971
  rejectVersion?: number | undefined;
972
972
  method: ABIMethod;
973
- args?: (Transaction | ABIValue | Promise<Transaction> | TransactionWithSigner | AppMethodCall<{
973
+ args?: (Transaction | ABIValue | TransactionWithSigner | AppMethodCall<{
974
974
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
975
975
  sender: SendingAddress;
976
976
  rekeyTo?: ReadableAddress | undefined;
@@ -987,7 +987,7 @@ declare class AlgorandClientTransactionCreator {
987
987
  accountReferences?: ReadableAddress[] | undefined;
988
988
  appReferences?: bigint[] | undefined;
989
989
  assetReferences?: bigint[] | undefined;
990
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
990
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
991
991
  accessReferences?: ResourceReference[] | undefined;
992
992
  rejectVersion?: number | undefined;
993
993
  appId?: 0 | undefined;
@@ -1000,7 +1000,7 @@ declare class AlgorandClientTransactionCreator {
1000
1000
  localByteSlices: number;
1001
1001
  } | undefined;
1002
1002
  extraProgramPages?: number | undefined;
1003
- }> | AppMethodCall<{
1003
+ }> | Promise<Transaction> | AppMethodCall<{
1004
1004
  sender: SendingAddress;
1005
1005
  signer?: AddressWithTransactionSigner | TransactionSigner | undefined;
1006
1006
  rekeyTo?: ReadableAddress | undefined;
@@ -1018,7 +1018,7 @@ declare class AlgorandClientTransactionCreator {
1018
1018
  accountReferences?: ReadableAddress[] | undefined;
1019
1019
  appReferences?: bigint[] | undefined;
1020
1020
  assetReferences?: bigint[] | undefined;
1021
- boxReferences?: (BoxIdentifier | BoxReference)[] | undefined;
1021
+ boxReferences?: (BoxReference | BoxIdentifier)[] | undefined;
1022
1022
  accessReferences?: ResourceReference[] | undefined;
1023
1023
  rejectVersion?: number | undefined;
1024
1024
  approvalProgram: string | Uint8Array;