diff --git a/lib/algorand.transaction.acfg.ts b/lib/algorand.transaction.acfg.ts index 95a33b0..e518d77 100644 --- a/lib/algorand.transaction.acfg.ts +++ b/lib/algorand.transaction.acfg.ts @@ -1,6 +1,6 @@ import {AlgorandEncoder} from "./algorand.encoder.js" import {AssetParams} from "./algorand.asset.params.js"; -import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.js"; +import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.header.js"; /** * This is used to create, configure and destroy an asset depending on which fields are set. diff --git a/lib/algorand.transaction.afrz.ts b/lib/algorand.transaction.afrz.ts index 80dc5b6..33e8ea7 100644 --- a/lib/algorand.transaction.afrz.ts +++ b/lib/algorand.transaction.afrz.ts @@ -1,5 +1,5 @@ import {AlgorandEncoder} from "./algorand.encoder.js" -import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.js"; +import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.header.js"; /** * Includes all fields in {@link TransactionHeader} and "type" is "axfer". diff --git a/lib/algorand.transaction.axfer.ts b/lib/algorand.transaction.axfer.ts index 6b58276..af315d7 100644 --- a/lib/algorand.transaction.axfer.ts +++ b/lib/algorand.transaction.axfer.ts @@ -1,5 +1,5 @@ import {AlgorandEncoder} from "./algorand.encoder.js" -import {TransactionHeader, type ITransactionHeaderBuilder} from "./algorand.transaction.js"; +import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.header.js"; /** * Asset Transfer Transaction diff --git a/lib/algorand.transaction.crafter.spec.ts b/lib/algorand.transaction.crafter.spec.ts index eab6047..579b385 100644 --- a/lib/algorand.transaction.crafter.spec.ts +++ b/lib/algorand.transaction.crafter.spec.ts @@ -11,7 +11,7 @@ import {AssetConfigTransaction} from "./algorand.transaction.acfg"; import {AssetParamsBuilder} from "./algorand.asset.params"; import {AssetTransferTransaction} from "./algorand.transaction.axfer"; import {AssetFreezeTransaction} from "./algorand.transaction.afrz"; -import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction"; +import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.header"; // Setup Validator @@ -111,14 +111,14 @@ describe("Algorand Transaction Crafter", () => { const from: string = algoEncoder.encodeAddress(Buffer.from(transactionHeader.snd)) // to algorand address const to: string = algoEncoder.encodeAddress(Buffer.from(randomBytes(32))) - + // create pay transaction const txn: PayTransaction = withTestTransactionHeader( algorandCrafter .pay(1000, from, to) .addCloseTo(from) ).get() - + expect(txn).toBeDefined() expect(txn).toBeInstanceOf(PayTransaction) expect(txn).toEqual({ @@ -131,7 +131,7 @@ describe("Algorand Transaction Crafter", () => { const validate = ajv.compile(paySchema) expect(validate(txn)).toBe(true) - }) + }) }) describe("KeyReg Online Transactions", () => { @@ -140,22 +140,22 @@ describe("Algorand Transaction Crafter", () => { it("(OK) Craft Keyreg change-online transaction", async () => { // from algorand address const from: string = algoEncoder.encodeAddress(Buffer.from(transactionHeader.snd)) - + // vote key const voteKey: string = Buffer.from(randomBytes(32)).toString("base64") - + // selection key const selectionKey: string = Buffer.from(randomBytes(32)).toString("base64") - + // state proof key const stateProofKey: string = Buffer.from(randomBytes(64)).toString("base64") - + // create keyreg transaction const txn: KeyregTransaction = withTestTransactionHeader( algorandCrafter .changeOnline(from, voteKey, selectionKey, stateProofKey, 1000, 2000, 32) ).get() - + expect(txn).toBeDefined() expect(txn).toBeInstanceOf(KeyregTransaction) @@ -181,12 +181,12 @@ describe("Algorand Transaction Crafter", () => { it("(OK) Craft Keyreg change-offline transaction", async () => { // from algorand address const from: string = algoEncoder.encodeAddress(Buffer.from(transactionHeader.snd)) - + // create keyreg transaction const txn: KeyregTransaction = withTestTransactionHeader(algorandCrafter .changeOffline(from) ).get() - + expect(txn).toBeDefined() expect(txn).toBeInstanceOf(KeyregTransaction) expect(txn).toEqual({ @@ -208,16 +208,16 @@ describe("Algorand Transaction Crafter", () => { it("(OK) Craft Keyreg non-participation transaction", async () => { // from algorand address const from: string = algoEncoder.encodeAddress(Buffer.from(transactionHeader.snd)) - + // note const note: string = Buffer.from(randomBytes(32)).toString("base64") - + // create keyreg transaction const txn: KeyregTransaction = withTestTransactionHeader( algorandCrafter .markNonParticipation(from) ).get() - + expect(txn).toBeDefined() expect(txn).toBeInstanceOf(KeyregTransaction) expect(txn).toEqual({ diff --git a/lib/algorand.transaction.header.ts b/lib/algorand.transaction.header.ts new file mode 100644 index 0000000..75405b0 --- /dev/null +++ b/lib/algorand.transaction.header.ts @@ -0,0 +1,156 @@ +/** + * Specifies the type of transaction. This value is automatically generated using any of the developer tools. + * @category Common + */ +export type TransactionType = "pay" | "keyreg" | "acfg" | "axfer" | "afrz" | "appl" | "stpf" + +/** + * + * Transaction Header + * + * Shared keys for all transactions + * + * @category Common + */ +export abstract class TransactionHeader { + /** + * Transaction Type + * + * Specifies the type of transaction. This value is automatically generated using any of the developer tools. + */ + type: TransactionType + /** + * Sender + * + * The address of the account that pays the fee and amount. + */ + snd: Uint8Array + /** + * Fee + * + * Paid by the sender to the FeeSink to prevent denial-of-service. The minimum fee on Algorand is currently 1000 microAlgos. + */ + fee: number + /** + * First Valid + * + * The first round for when the transaction is valid. If the transaction is sent prior to this round it will be rejected by the network. + */ + fv: number + /** + * Last Valid + * + * The ending round for which the transaction is valid. After this round, the transaction will be rejected by the network. + */ + lv: number + /** + * Genesis Hash + * + * The hash of the genesis block of the network for which the transaction is valid. See the genesis hash for MainNet, TestNet, and BetaNet. + */ + gh: Uint8Array + /** + * Genesis ID + * + * The human-readable string that identifies the network for the transaction. + * The genesis ID is found in the genesis block. See the genesis ID for MainNet, TestNet, and BetaNet. + */ + gen?: string + /** + * Note + * + * Any data up to 1000 bytes. + */ + note?: Uint8Array + /** + * Rekey To + * + * Specifies the authorized address. This address will be used to authorize all future transactions. + */ + rekey?: Uint8Array + /** + * Lease + * + * A lease enforces mutual exclusion of transactions. If this field is nonzero, then once the transaction is confirmed, + * it acquires the lease identified by the (Sender, Lease) pair of the transaction until the LastValid round passes. + * While this transaction possesses the lease, no other transaction specifying this lease can be confirmed. + * A lease is often used in the context of Algorand Smart Contracts to prevent replay attacks. + * Read more about Algorand Smart Contracts. Leases can also be used to safeguard against unintended duplicate spends. + * For example, if I send a transaction to the network and later realize my fee was too low, + * I could send another transaction with a higher fee, but the same lease value. + * This would ensure that only one of those transactions ends up getting confirmed during the validity period. + */ + lx?: Uint8Array + /** + * Group + * + * The group specifies that the transaction is part of a group and, if so, specifies the hash of the transaction group. + * Assign a group ID to a transaction through the workflow described in the Atomic Transfers Guide. + */ + grp?: Uint8Array +} + +/** + * Interface for Transaction Header Builders + * @category Builders + * @internal + */ +export interface ITransactionHeaderBuilder { + /** + * Add Sender + * + * @param sender The address of the account that pays the fee and amount. + */ + addSender(sender: string): T + + /** + * Add Fee + * + * @param fee Paid by the sender to the FeeSink to prevent denial-of-service. The minimum fee on Algorand is currently 1000 microAlgos. + */ + addFee(fee: number): T + + /** + * Add First Valid Round + * + * @param fv The first round for when the transaction is valid. If the transaction is sent prior to this round it will be rejected by the network. + */ + addFirstValidRound(fv: number): T + + /** + * Add Last Valid Round + * + * @param lv The ending round for which the transaction is valid. After this round, the transaction will be rejected by the network. + */ + addLastValidRound(lv: number): T + + /** + * Add Note + * + * @param note Any data up to 1000 bytes. + * @param encoding + */ + addNote(note: string, encoding?: BufferEncoding): T + + /** + * Add Rekey Address + * + * @param rekey Specifies the authorized address. This address will be used to authorize all future transactions. + */ + addRekey(rekey: string): T + + /** + * Add Lease + * + * @param lx A lease enforces mutual exclusion of transactions. If this field is nonzero, then once the transaction + * is confirmed, it acquires the lease identified by the (Sender, Lease) pair of the transaction until the LastValid round passes. + */ + addLease(lx: Uint8Array): T + + /** + * Add Group + * + * @param grp The group specifies that the transaction is part of a group and, if so, specifies the hash of the transaction group. + */ + addGroup(grp: Uint8Array): T +} diff --git a/lib/algorand.transaction.keyreg.ts b/lib/algorand.transaction.keyreg.ts index bbb83e8..e18aa0c 100644 --- a/lib/algorand.transaction.keyreg.ts +++ b/lib/algorand.transaction.keyreg.ts @@ -1,5 +1,6 @@ import {AlgorandEncoder} from "./algorand.encoder.js" -import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.js"; +import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.header.js"; + /** * @category Transactions * @see {@link AlgorandTransactionCrafter} diff --git a/lib/algorand.transaction.pay.ts b/lib/algorand.transaction.pay.ts index b96b682..b751f54 100644 --- a/lib/algorand.transaction.pay.ts +++ b/lib/algorand.transaction.pay.ts @@ -1,5 +1,5 @@ import {AlgorandEncoder} from "./algorand.encoder.js" -import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.js"; +import {ITransactionHeaderBuilder, TransactionHeader} from "./algorand.transaction.header.js"; /** * @category Transactions diff --git a/lib/algorand.transaction.ts b/lib/algorand.transaction.ts index 8c12353..3b17025 100644 --- a/lib/algorand.transaction.ts +++ b/lib/algorand.transaction.ts @@ -12,159 +12,3 @@ import {KeyregTransaction} from "./algorand.transaction.keyreg.js"; * @category Common */ export type Transaction = PayTransaction | AssetConfigTransaction | AssetTransferTransaction | AssetFreezeTransaction | KeyregTransaction -/** - * Specifies the type of transaction. This value is automatically generated using any of the developer tools. - * @category Common - */ -export type TransactionType = "pay" | "keyreg" | "acfg" | "axfer" | "afrz" | "appl" | "stpf" - -/** - * - * Transaction Header - * - * Shared keys for all transactions - * - * @category Common - */ -export abstract class TransactionHeader { - /** - * Transaction Type - * - * Specifies the type of transaction. This value is automatically generated using any of the developer tools. - */ - type: TransactionType - /** - * Sender - * - * The address of the account that pays the fee and amount. - */ - snd: Uint8Array - /** - * Fee - * - * Paid by the sender to the FeeSink to prevent denial-of-service. The minimum fee on Algorand is currently 1000 microAlgos. - */ - fee: number - /** - * First Valid - * - * The first round for when the transaction is valid. If the transaction is sent prior to this round it will be rejected by the network. - */ - fv: number - /** - * Last Valid - * - * The ending round for which the transaction is valid. After this round, the transaction will be rejected by the network. - */ - lv: number - /** - * Genesis Hash - * - * The hash of the genesis block of the network for which the transaction is valid. See the genesis hash for MainNet, TestNet, and BetaNet. - */ - gh: Uint8Array - /** - * Genesis ID - * - * The human-readable string that identifies the network for the transaction. - * The genesis ID is found in the genesis block. See the genesis ID for MainNet, TestNet, and BetaNet. - */ - gen?: string - /** - * Note - * - * Any data up to 1000 bytes. - */ - note?: Uint8Array - /** - * Rekey To - * - * Specifies the authorized address. This address will be used to authorize all future transactions. - */ - rekey?: Uint8Array - /** - * Lease - * - * A lease enforces mutual exclusion of transactions. If this field is nonzero, then once the transaction is confirmed, - * it acquires the lease identified by the (Sender, Lease) pair of the transaction until the LastValid round passes. - * While this transaction possesses the lease, no other transaction specifying this lease can be confirmed. - * A lease is often used in the context of Algorand Smart Contracts to prevent replay attacks. - * Read more about Algorand Smart Contracts. Leases can also be used to safeguard against unintended duplicate spends. - * For example, if I send a transaction to the network and later realize my fee was too low, - * I could send another transaction with a higher fee, but the same lease value. - * This would ensure that only one of those transactions ends up getting confirmed during the validity period. - */ - lx?: Uint8Array - /** - * Group - * - * The group specifies that the transaction is part of a group and, if so, specifies the hash of the transaction group. - * Assign a group ID to a transaction through the workflow described in the Atomic Transfers Guide. - */ - grp?: Uint8Array -} - -/** - * Interface for Transaction Header Builders - * @category Builders - * @internal - */ -export interface ITransactionHeaderBuilder { - /** - * Add Sender - * - * @param sender The address of the account that pays the fee and amount. - */ - addSender(sender: string): T - - /** - * Add Fee - * - * @param fee Paid by the sender to the FeeSink to prevent denial-of-service. The minimum fee on Algorand is currently 1000 microAlgos. - */ - addFee(fee: number): T - - /** - * Add First Valid Round - * - * @param fv The first round for when the transaction is valid. If the transaction is sent prior to this round it will be rejected by the network. - */ - addFirstValidRound(fv: number): T - - /** - * Add Last Valid Round - * - * @param lv The ending round for which the transaction is valid. After this round, the transaction will be rejected by the network. - */ - addLastValidRound(lv: number): T - - /** - * Add Note - * - * @param note Any data up to 1000 bytes. - * @param encoding - */ - addNote(note: string, encoding?: BufferEncoding): T - - /** - * Add Rekey Address - * - * @param rekey Specifies the authorized address. This address will be used to authorize all future transactions. - */ - addRekey(rekey: string): T - - /** - * Add Lease - * - * @param lx A lease enforces mutual exclusion of transactions. If this field is nonzero, then once the transaction - * is confirmed, it acquires the lease identified by the (Sender, Lease) pair of the transaction until the LastValid round passes. - */ - addLease(lx: Uint8Array): T - - /** - * Add Group - * - * @param grp The group specifies that the transaction is part of a group and, if so, specifies the hash of the transaction group. - */ - addGroup(grp: Uint8Array): T -} \ No newline at end of file diff --git a/lib/index.ts b/lib/index.ts index 82c48e1..f93fde7 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -15,4 +15,5 @@ export * from './algorand.transaction.pay.js' // Common export * from './algorand.asset.params.js' +export * from './algorand.transaction.header.js' export * from './algorand.transaction.js' diff --git a/package-lock.json b/package-lock.json index a8e4511..b3ed659 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@algorandfoundation/algo-models", - "version": "0.0.4", + "version": "0.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@algorandfoundation/algo-models", - "version": "0.0.4", + "version": "0.0.5", "license": "AGPL-3.0-or-later", "dependencies": { "ajv": "^8.12.0", @@ -1472,12 +1472,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -1722,10 +1723,11 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, + "license": "MIT", "peer": true, "dependencies": { "path-key": "^3.1.0", @@ -1952,10 +1954,11 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2223,6 +2226,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -3206,12 +3210,13 @@ "peer": true }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -3879,6 +3884,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, diff --git a/package.json b/package.json index 7bbf6d8..56d86e7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@algorandfoundation/algo-models", - "version": "0.0.4", + "version": "0.0.5", "description": "", "main": "dist/cjs/index.js", "module": "dist/esm/index.js",