diff --git a/docs/code/classes/types_account_manager.AccountManager.md b/docs/code/classes/types_account_manager.AccountManager.md index c2072f797..168c36489 100644 --- a/docs/code/classes/types_account_manager.AccountManager.md +++ b/docs/code/classes/types_account_manager.AccountManager.md @@ -185,7 +185,7 @@ ___ #### Defined in -[src/types/account-manager.ts:547](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L547) +[src/types/account-manager.ts:563](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L563) ___ @@ -215,7 +215,7 @@ const account = await accountManager.dispenserFromEnvironment() #### Defined in -[src/types/account-manager.ts:460](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L460) +[src/types/account-manager.ts:476](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L476) ___ @@ -258,7 +258,7 @@ await accountManager.ensureFunded("ACCOUNTADDRESS", "DISPENSERADDRESS", algokit. #### Defined in -[src/types/account-manager.ts:580](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L580) +[src/types/account-manager.ts:596](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L596) ___ @@ -307,7 +307,7 @@ await accountManager.ensureFundedFromEnvironment("ACCOUNTADDRESS", algokit.algo( #### Defined in -[src/types/account-manager.ts:642](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L642) +[src/types/account-manager.ts:658](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L658) ___ @@ -351,7 +351,7 @@ await accountManager.ensureFundedFromTestNetDispenserApi("ACCOUNTADDRESS", algor #### Defined in -[src/types/account-manager.ts:698](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L698) +[src/types/account-manager.ts:714](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L714) ___ @@ -587,7 +587,7 @@ const account = await accountManager.localNetDispenser() #### Defined in -[src/types/account-manager.ts:479](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L479) +[src/types/account-manager.ts:495](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L495) ___ @@ -656,13 +656,13 @@ ___ ### random -▸ **random**(): [`Address`](index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } } +▸ **random**(): [`Address`](index.Address.md) & \{ `addr`: `Readonly`\<[`Address`](index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } Tracks and returns a new, random Algorand account with secret key loaded. #### Returns -[`Address`](index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } } +[`Address`](index.Address.md) & \{ `addr`: `Readonly`\<[`Address`](index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } The account @@ -734,7 +734,7 @@ await accountManager.rekeyAccount({ #### Defined in -[src/types/account-manager.ts:522](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L522) +[src/types/account-manager.ts:538](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/account-manager.ts#L538) ___ diff --git a/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md b/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md index cf71144f2..9ea8d25f1 100644 --- a/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md +++ b/docs/code/interfaces/types_testing.AlgoKitLogCaptureFixture.md @@ -33,7 +33,7 @@ Testing framework agnostic handler method to run after each test to reset the lo #### Defined in -[src/types/testing.ts:156](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L156) +[src/types/testing.ts:190](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L190) ___ @@ -53,7 +53,7 @@ Testing framework agnostic handler method to run before each test to prepare the #### Defined in -[src/types/testing.ts:152](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L152) +[src/types/testing.ts:186](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L186) ## Accessors @@ -69,4 +69,4 @@ The test logger instance for the current test #### Defined in -[src/types/testing.ts:148](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L148) +[src/types/testing.ts:182](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L182) diff --git a/docs/code/interfaces/types_testing.AlgorandFixture.md b/docs/code/interfaces/types_testing.AlgorandFixture.md index 7b81c0a2d..e4bf89281 100644 --- a/docs/code/interfaces/types_testing.AlgorandFixture.md +++ b/docs/code/interfaces/types_testing.AlgorandFixture.md @@ -39,7 +39,7 @@ Testing framework agnostic handler method to run before each test to prepare the #### Defined in -[src/types/testing.ts:88](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L88) +[src/types/testing.ts:122](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L122) ___ @@ -95,7 +95,7 @@ describe('MY MODULE', () => { #### Defined in -[src/types/testing.ts:128](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L128) +[src/types/testing.ts:162](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L162) ## Accessors @@ -111,7 +111,7 @@ Retrieve an `AlgorandClient` loaded with the current context, including testAcco #### Defined in -[src/types/testing.ts:82](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L82) +[src/types/testing.ts:116](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L116) ___ @@ -138,4 +138,4 @@ test('My test', () => { #### Defined in -[src/types/testing.ts:77](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L77) +[src/types/testing.ts:111](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L111) diff --git a/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md b/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md index b8028a21d..07075f86d 100644 --- a/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md +++ b/docs/code/interfaces/types_testing.AlgorandFixtureConfig.md @@ -29,13 +29,13 @@ Configuration for creating an Algorand testing fixture. ### accountGetter -• `Optional` **accountGetter**: (`algod`: `AlgodClient`, `kmd?`: `KmdClient`) => `Promise`\<\{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` }\> +• `Optional` **accountGetter**: (`algod`: `AlgodClient`, `kmd?`: `KmdClient`) => `Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } }\> Optional override for how to get an account; this allows you to retrieve accounts from a known or cached list of accounts. #### Type declaration -▸ (`algod`, `kmd?`): `Promise`\<\{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` }\> +▸ (`algod`, `kmd?`): `Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } }\> ##### Parameters @@ -46,11 +46,11 @@ Optional override for how to get an account; this allows you to retrieve account ##### Returns -`Promise`\<\{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` }\> +`Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } }\> #### Defined in -[src/types/testing.ts:60](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L60) +[src/types/testing.ts:80](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L80) ___ @@ -62,7 +62,7 @@ An optional algod client, if not specified then it will create one against `algo #### Defined in -[src/types/testing.ts:52](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L52) +[src/types/testing.ts:72](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L72) ___ @@ -90,7 +90,7 @@ An optional indexer client, if not specified then it will create one against `in #### Defined in -[src/types/testing.ts:54](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L54) +[src/types/testing.ts:74](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L74) ___ @@ -118,7 +118,7 @@ An optional kmd client, if not specified then it will create one against `kmdCon #### Defined in -[src/types/testing.ts:56](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L56) +[src/types/testing.ts:76](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L76) ___ @@ -146,4 +146,4 @@ The amount of funds to allocate to the default testing account, if not specified #### Defined in -[src/types/testing.ts:58](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L58) +[src/types/testing.ts:78](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L78) diff --git a/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md b/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md index d13ae0ad1..ef50d14d6 100644 --- a/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md +++ b/docs/code/interfaces/types_testing.AlgorandTestAutomationContext.md @@ -30,7 +30,7 @@ Algod client instance that will log transactions in `transactionLogger` #### Defined in -[src/types/testing.ts:20](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L20) +[src/types/testing.ts:29](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L29) ___ @@ -42,7 +42,7 @@ An AlgorandClient instance loaded with the current context, including testAccoun #### Defined in -[src/types/testing.ts:18](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L18) +[src/types/testing.ts:27](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L27) ___ @@ -68,7 +68,7 @@ Generate and fund an additional ephemerally created account #### Defined in -[src/types/testing.ts:30](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L30) +[src/types/testing.ts:39](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L39) ___ @@ -80,7 +80,7 @@ Indexer client instance #### Defined in -[src/types/testing.ts:22](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L22) +[src/types/testing.ts:31](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L31) ___ @@ -92,7 +92,7 @@ KMD client instance #### Defined in -[src/types/testing.ts:24](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L24) +[src/types/testing.ts:33](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L33) ___ @@ -104,7 +104,7 @@ Default, funded test account that is ephemerally created #### Defined in -[src/types/testing.ts:28](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L28) +[src/types/testing.ts:37](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L37) ___ @@ -116,7 +116,7 @@ Transaction logger that will log transaction IDs for all transactions issued by #### Defined in -[src/types/testing.ts:26](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L26) +[src/types/testing.ts:35](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L35) ___ @@ -136,7 +136,7 @@ Wait for the indexer to catch up with all transactions logged by `transactionLog #### Defined in -[src/types/testing.ts:32](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L32) +[src/types/testing.ts:41](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L41) ___ @@ -162,4 +162,4 @@ Wait for the indexer to catch up with the given transaction ID #### Defined in -[src/types/testing.ts:34](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L34) +[src/types/testing.ts:43](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L43) diff --git a/docs/code/interfaces/types_testing.GetTestAccountParams.md b/docs/code/interfaces/types_testing.GetTestAccountParams.md index c3e7a1700..9e3eeb19c 100644 --- a/docs/code/interfaces/types_testing.GetTestAccountParams.md +++ b/docs/code/interfaces/types_testing.GetTestAccountParams.md @@ -18,13 +18,13 @@ Parameters for the `getTestAccount` function. ### accountGetter -• `Optional` **accountGetter**: (`algorand`: [`AlgorandClient`](../classes/types_algorand_client.AlgorandClient.md)) => `Promise`\<\{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` }\> +• `Optional` **accountGetter**: (`algorand`: [`AlgorandClient`](../classes/types_algorand_client.AlgorandClient.md)) => `Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } }\> Optional override for how to get a test account; this allows you to retrieve accounts from a known or cached list of accounts. #### Type declaration -▸ (`algorand`): `Promise`\<\{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` }\> +▸ (`algorand`): `Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } }\> ##### Parameters @@ -34,11 +34,11 @@ Optional override for how to get a test account; this allows you to retrieve acc ##### Returns -`Promise`\<\{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` }\> +`Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithTransactionSigner` & \{ `account`: \{ `addr`: `Readonly`\<[`Address`](../classes/index.Address.md)\> ; `lsigSigner`: `DelegatedLsigSigner` ; `mxBytesSigner`: `MxBytesSigner` ; `programDataSigner`: `ProgramDataSigner` ; `signer`: `TransactionSigner` } }\> #### Defined in -[src/types/testing.ts:46](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L46) +[src/types/testing.ts:55](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L55) ___ @@ -50,7 +50,7 @@ Initial funds to ensure the account has #### Defined in -[src/types/testing.ts:42](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L42) +[src/types/testing.ts:51](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L51) ___ @@ -62,4 +62,4 @@ Whether to suppress the log (which includes a mnemonic) or not (default: do not #### Defined in -[src/types/testing.ts:44](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L44) +[src/types/testing.ts:53](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L53) diff --git a/docs/code/interfaces/types_testing.LogSnapshotConfig.md b/docs/code/interfaces/types_testing.LogSnapshotConfig.md index 8b0f8b947..e26cc6770 100644 --- a/docs/code/interfaces/types_testing.LogSnapshotConfig.md +++ b/docs/code/interfaces/types_testing.LogSnapshotConfig.md @@ -27,7 +27,7 @@ Any accounts/addresses to replace the address for predictably #### Defined in -[src/types/testing.ts:139](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L139) +[src/types/testing.ts:173](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L173) ___ @@ -39,7 +39,7 @@ Any app IDs to replace predictably #### Defined in -[src/types/testing.ts:141](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L141) +[src/types/testing.ts:175](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L175) ___ @@ -65,7 +65,7 @@ Optional filter predicate to filter out logs #### Defined in -[src/types/testing.ts:143](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L143) +[src/types/testing.ts:177](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L177) ___ @@ -77,4 +77,4 @@ Any transaction IDs or transactions to replace the ID for predictably #### Defined in -[src/types/testing.ts:137](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L137) +[src/types/testing.ts:171](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L171) diff --git a/docs/code/modules/testing.md b/docs/code/modules/testing.md index c5ed8ff4b..e74ed88fa 100644 --- a/docs/code/modules/testing.md +++ b/docs/code/modules/testing.md @@ -178,7 +178,7 @@ Note: By default this will log the mnemonic of the account. #### Defined in -[src/testing/account.ts:20](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/account.ts#L20) +[src/testing/account.ts:23](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/account.ts#L23) ▸ **getTestAccount**(`params`, `algorand`): `Promise`\<[`Address`](../classes/index.Address.md) & `AddressWithSigners`\> @@ -202,7 +202,7 @@ The account, with private key loaded #### Defined in -[src/testing/account.ts:34](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/account.ts#L34) +[src/testing/account.ts:37](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/account.ts#L37) ___ diff --git a/packages/transact/src/logicsig.spec.ts b/packages/transact/src/logicsig.spec.ts index 1deca75c5..9478b5a84 100644 --- a/packages/transact/src/logicsig.spec.ts +++ b/packages/transact/src/logicsig.spec.ts @@ -1,4 +1,4 @@ -import { encodeMsgpack } from '@algorandfoundation/algokit-common' +import { Address, encodeMsgpack } from '@algorandfoundation/algokit-common' import { describe, expect, test } from 'vitest' import { LogicSigAccount } from './logicsig' import { LogicSignature } from './transactions/signed-transaction' @@ -15,7 +15,7 @@ describe('logicsig', () => { } satisfies LogicSignature const encoded = encodeMsgpack(logicSignatureCodec.encode(logicSignature, 'msgpack')) - const decoded = LogicSigAccount.fromBytes(encoded) + const decoded = LogicSigAccount.fromBytes(encoded, Address.zeroAddress()) expect(decoded.logic).toEqual(logicSignature.logic) expect(decoded.sig).toEqual(signature) diff --git a/packages/transact/src/logicsig.ts b/packages/transact/src/logicsig.ts index a8aeb8900..6650e973b 100644 --- a/packages/transact/src/logicsig.ts +++ b/packages/transact/src/logicsig.ts @@ -1,6 +1,6 @@ -import { Address, concatArrays, decodeMsgpack, hash } from '@algorandfoundation/algokit-common' +import { Address, Addressable, concatArrays, decodeMsgpack, hash } from '@algorandfoundation/algokit-common' import { MultisigAccount } from './multisig' -import { TransactionSigner } from './signer' +import { AddressWithDelegatedLsigSigner, TransactionSigner } from './signer' import { LogicSignature, MultisigSignature, SignedTransaction, encodeSignedTransaction } from './transactions/signed-transaction' import { Transaction } from './transactions/transaction' import { logicSignatureCodec } from './transactions/signed-transaction-meta' @@ -9,43 +9,117 @@ const PROGRAM_TAG = new TextEncoder().encode('Program') const MSIG_PROGRAM_TAG = new TextEncoder().encode('MsigProgram') const SIGN_PROGRAM_DATA_PREFIX = new TextEncoder().encode('ProgData') -/** Function for signing logic signatures for delegation */ -export type DelegatedLsigSigner = (lsig: LogicSigAccount, msig?: MultisigAccount) => Promise +/** Function for signing logic signatures for delegation + * @param lsig - The logic signature that is being signed for delegation + * @param msig - Optional multisig account that should be set when a public key is signing as a subsigner of a multisig + * @returns The address of the delegator + * */ +export type DelegatedLsigSigner = ( + lsig: LogicSigAccount, + msig?: MultisigAccount, +) => Promise<{ addr: Address } & ({ sig?: Uint8Array } | { lmsig?: MultisigSignature })> /** Function for signing program data for a logic signature */ -export type ProgramDataSigner = (data: Uint8Array, lsig: LogicSigAccount) => Promise +export type ProgramDataSigner = (data: Uint8Array, lsig: LogicSig) => Promise -export class LogicSigAccount { +export class LogicSig implements Addressable { logic: Uint8Array args: Uint8Array[] + protected _addr: Address + + constructor(program: Uint8Array, programArgs?: Array) { + this.logic = program + this.args = programArgs ?? [] + const toBeSigned = concatArrays(PROGRAM_TAG, this.logic) + const h = hash(toBeSigned) + this._addr = new Address(h) + } + + static fromSignature(signature: LogicSignature): LogicSig { + return new LogicSig(signature.logic, signature.args || []) + } + + static fromBytes(encodedLsig: Uint8Array): LogicSig { + const decoded = decodeMsgpack(encodedLsig) + const lsigSignature = logicSignatureCodec.decode(decoded, 'msgpack') + return LogicSig.fromSignature(lsigSignature) + } + + address(): Address { + return this._addr + } + + get addr(): Address { + return this._addr + } + + bytesToSignForDelegation(msig?: MultisigAccount): Uint8Array { + if (msig) { + return concatArrays(MSIG_PROGRAM_TAG, msig.addr.publicKey, this.logic) + } else { + return concatArrays(PROGRAM_TAG, this.logic) + } + } + + signProgramData(data: Uint8Array, signer: ProgramDataSigner): Promise { + return signer(data, this) + } + + programDataToSign(data: Uint8Array): Uint8Array { + return concatArrays(SIGN_PROGRAM_DATA_PREFIX, this.address().publicKey, data) + } + + account(): LogicSigAccount { + return new LogicSigAccount(this.logic, this.args) + } + + delegatedAccount(delegator: Address): LogicSigAccount { + return new LogicSigAccount(this.logic, this.args, delegator) + } +} + +export class LogicSigAccount extends LogicSig { sig?: Uint8Array msig?: MultisigSignature lmsig?: MultisigSignature - static fromSignature(signature: LogicSignature): LogicSigAccount { - const lsigAccount = new LogicSigAccount(signature.logic, signature.args || []) - lsigAccount.sig = signature.sig - lsigAccount.msig = signature.msig - lsigAccount.lmsig = signature.lmsig + static fromSignature(signature: LogicSignature, delegator?: Address): LogicSigAccount { + if (signature.lmsig || signature.msig) { + const msigAddr = MultisigAccount.fromSignature((signature.lmsig || signature.msig)!).addr + + if (delegator && !msigAddr.equals(delegator)) { + throw new Error('Provided delegator address does not match multisig address') + } + + const lsig = new LogicSigAccount(signature.logic, signature.args || [], msigAddr) + lsig.lmsig = signature.lmsig + lsig.msig = signature.msig + return lsig + } + + const lsigAccount = new LogicSigAccount(signature.logic, signature.args || [], delegator) + + if (signature.sig && delegator === undefined) { + throw new Error('Delegated address must be provided when logic sig has a signature') + } + + if (signature.sig) { + lsigAccount.sig = signature.sig + return lsigAccount + } + return lsigAccount } - static fromBytes(encodedLsig: Uint8Array): LogicSigAccount { + static fromBytes(encodedLsig: Uint8Array, delegator?: Address): LogicSigAccount { const decoded = decodeMsgpack(encodedLsig) const lsigSignature = logicSignatureCodec.decode(decoded, 'msgpack') - return LogicSigAccount.fromSignature(lsigSignature) + return LogicSigAccount.fromSignature(lsigSignature, delegator) } - constructor(program: Uint8Array, programArgs?: Array | null) { - if (programArgs && (!Array.isArray(programArgs) || !programArgs.every((arg) => arg.constructor === Uint8Array))) { - throw new TypeError('Invalid arguments') - } - - let args: Uint8Array[] = [] - if (programArgs != null) args = programArgs.map((arg) => new Uint8Array(arg)) - - this.logic = program - this.args = args + constructor(program: Uint8Array, programArgs?: Array | null, delegator?: Address) { + super(program, programArgs ?? undefined) + this._addr = delegator ?? this._addr } get signer(): TransactionSigner { @@ -59,6 +133,10 @@ export class LogicSigAccount { lsig: { logic: this.logic, args: this.args, msig: this.msig, lmsig: this.lmsig, sig: this.sig }, } + if (!stxn.txn.sender.equals(this.addr)) { + stxn.authAddress = this.addr + } + signedTxns.push(encodeSignedTransaction(stxn)) } @@ -66,53 +144,21 @@ export class LogicSigAccount { } } - get addr(): Address { - return this.address() - } - - /** - * Compute hash of the logic sig program (that is the same as escrow account address) as string address - * @returns String representation of the address - */ - address(): Address { - const toBeSigned = concatArrays(PROGRAM_TAG, this.logic) - const h = hash(toBeSigned) - return new Address(h) - } - - async delegate(signer: DelegatedLsigSigner) { - this.sig = await signer(this) - } - - async delegateMultisig(msig: MultisigAccount) { - if (this.lmsig == undefined) { - this.lmsig = { - subsigs: [], - version: msig.params.version, - threshold: msig.params.threshold, - } - } - for (const addrWithSigner of msig.subSigners) { - const { lsigSigner, addr } = addrWithSigner - const signature = await lsigSigner(this, msig) + async signForDelegation(delegator: AddressWithDelegatedLsigSigner) { + const result = await delegator.lsigSigner(this) - this.lmsig.subsigs.push({ publicKey: addr.publicKey, sig: signature }) + if (!result.addr.equals(this._addr)) { + throw new Error( + `Delegator address from signer does not match expected delegator address. Expected: ${this._addr.toString()}, got: ${result.addr.toString()}`, + ) } - } - bytesToSignForDelegation(msig?: MultisigAccount): Uint8Array { - if (msig) { - return concatArrays(MSIG_PROGRAM_TAG, msig.addr.publicKey, this.logic) + if ('sig' in result && result.sig) { + this.sig = result.sig + } else if ('lmsig' in result && result.lmsig) { + this.lmsig = result.lmsig } else { - return concatArrays(PROGRAM_TAG, this.logic) + throw new Error('Delegated lsig signer must return either a sig or lmsig') } } - - signProgramData(data: Uint8Array, signer: ProgramDataSigner): Promise { - return signer(data, this) - } - - programDataToSign(data: Uint8Array): Uint8Array { - return concatArrays(SIGN_PROGRAM_DATA_PREFIX, this.address().publicKey, data) - } } diff --git a/packages/transact/src/multisig.ts b/packages/transact/src/multisig.ts index 75cfc4a9c..b0312fa7d 100644 --- a/packages/transact/src/multisig.ts +++ b/packages/transact/src/multisig.ts @@ -17,6 +17,7 @@ import { SignedTransaction, } from './transactions/signed-transaction' import { Transaction } from './transactions/transaction' +import { DelegatedLsigSigner } from './logicsig' const toPublicKeys = (addrs: Array): Uint8Array[] => addrs.map((addr) => getAddress(addr).publicKey) @@ -382,11 +383,12 @@ export interface MultisigMetadata { } /** Account wrapper that supports partial or full multisig signing. */ -export class MultisigAccount implements AddressWithTransactionSigner { +export class MultisigAccount implements AddressWithTransactionSigner, AddressWithDelegatedLsigSigner { _params: MultisigMetadata _subSigners: (AddressWithTransactionSigner & AddressWithDelegatedLsigSigner)[] _addr: Address _signer: TransactionSigner + _lsigSigner: DelegatedLsigSigner /** The parameters for the multisig account */ get params(): Readonly { @@ -408,6 +410,10 @@ export class MultisigAccount implements AddressWithTransactionSigner { return this._signer } + get lsigSigner(): DelegatedLsigSigner { + return this._lsigSigner + } + static fromSignature(signature: MultisigSignature): MultisigAccount { const params: MultisigMetadata = { version: signature.version, @@ -447,6 +453,24 @@ export class MultisigAccount implements AddressWithTransactionSigner { return signedMsigTxns.map(encodeSignedTransaction) } + + this._lsigSigner = async (lsig, _) => { + let lmsig = lsig.lmsig ?? this.createMultisigSignature() + + for (const addrWithSigner of this.subSigners) { + const { lsigSigner, addr } = addrWithSigner + const result = await lsigSigner(lsig, this) + if (!('sig' in result) || !result.sig) { + throw new Error( + `Signer for address ${addr.toString()} did not produce a valid signature when signing logic sig for multisig account ${this._addr.toString()}`, + ) + } + + lmsig = this.applySignature(lmsig, addr.publicKey, result.sig) + } + + return { addr: this.addr, lmsig } + } } createMultisigTransaction(txn: Transaction): SignedTransaction { diff --git a/packages/transact/src/signer.ts b/packages/transact/src/signer.ts index dc6e62808..b98e14151 100644 --- a/packages/transact/src/signer.ts +++ b/packages/transact/src/signer.ts @@ -75,7 +75,8 @@ export function generateAddressWithSigners(args: { const lsigSigner: DelegatedLsigSigner = async (lsig, msig) => { const bytesToSign = lsig.bytesToSignForDelegation(msig) - return await rawEd25519Signer(bytesToSign) + const sig = await rawEd25519Signer(bytesToSign) + return { sig, addr: sendingAddress } } const programDataSigner: ProgramDataSigner = async (data, lsig) => { diff --git a/src/testing/account.ts b/src/testing/account.ts index 7dafc1855..ba9875a5b 100644 --- a/src/testing/account.ts +++ b/src/testing/account.ts @@ -1,6 +1,9 @@ import { AlgodClient } from '@algorandfoundation/algokit-algod-client' import { Address } from '@algorandfoundation/algokit-common' -import { AddressWithSigners, AddressWithTransactionSigner } from '@algorandfoundation/algokit-transact' +import { + AddressWithSigners, + AddressWithTransactionSigner, +} from '@algorandfoundation/algokit-transact' import { KmdClient } from '@algorandfoundation/algokit-kmd-client' import { AlgorandClient, Config } from '../' import { GetTestAccountParams } from '../types/testing' @@ -36,7 +39,7 @@ export async function getTestAccount( { suppressLog, initialFunds, accountGetter }: GetTestAccountParams, algodOrAlgorandClient: AlgodClient | AlgorandClient, kmd?: KmdClient, -): Promise
{ +): Promise
{ const algorand = algodOrAlgorandClient instanceof AlgorandClient ? algodOrAlgorandClient @@ -65,10 +68,13 @@ export async function getTestAccount( algorand.setSignerFromAccount(account) - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const address = Address.fromString(account.addr.toString()) as any - address.addr = account.addr - address.signer = algorand.account.getSigner(address) + const address = Address.fromString(account.addr.toString()) as Address & AddressWithSigners + for (const key of Object.keys(account as AddressWithSigners)) { + if (!(key in address)) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(address as any)[key] = (account as any)[key] + } + } return address } diff --git a/src/types/account-manager.spec.ts b/src/types/account-manager.spec.ts index cd17c8189..142ef4233 100644 --- a/src/types/account-manager.spec.ts +++ b/src/types/account-manager.spec.ts @@ -1,5 +1,5 @@ import { secretKeyToMnemonic } from '@algorandfoundation/algokit-algo25' -import { generateAddressWithSigners } from '@algorandfoundation/algokit-transact' +import { generateAddressWithSigners, LogicSigAccount, MultisigAccount } from '@algorandfoundation/algokit-transact' import nacl from 'tweetnacl' import { v4 as uuid } from 'uuid' import { beforeEach, describe, expect, test } from 'vitest' @@ -60,44 +60,48 @@ describe('AccountManager', () => { expect(accountInfo.authAddr!.toString()).toBe(rekeyTo.addr.toString()) }, 10e6) - // TODO: This will be fixed in a future PR - // test('Logicsig account lmsig signing is supported', async () => { - // const { algorand, generateAccount, testAccount } = localnet.context - // const account1 = await generateAccount({ initialFunds: algo(1) }) - // const account2 = await generateAccount({ initialFunds: algo(1) }) - // const account3 = await generateAccount({ initialFunds: algo(1) }) - - // // Setup the multisig delegated logicsig - // const lsigAccount = new algosdk.LogicSigAccount( - // Uint8Array.from([1, 32, 1, 1, 34]), // int 1 - // [Uint8Array.from([1]), Uint8Array.from([2, 3])], - // ) - // lsigAccount.signMultisig( - // { - // version: 1, - // threshold: 2, - // addrs: [account1.addr, account2.addr, account3.addr], - // } satisfies algosdk.MultisigMetadata, - // account1.sk, - // ) // Make a 2 of 3 multisig delegated logicsig and sign with the first account - // lsigAccount.appendToMultisig(account2.sk) // sign with the second account - // await localnet.algorand.account.ensureFunded(lsigAccount.address(), testAccount, algo(1)) // Fund the lsig account - - // algorand.setSignerFromAccount(lsigAccount) - - // const result = await algorand.send.payment({ - // sender: lsigAccount.address(), - // receiver: testAccount.addr, - // amount: algo(0.1), - // }) - - // expect(result.confirmation.txn.lsig?.msig).toBeUndefined() - // expect(result.confirmation.txn.lsig?.lmsig).toBeDefined() - // expect(result.confirmation.txn.lsig?.lmsig?.threshold).toBe(2) - // expect(result.confirmation.txn.lsig?.lmsig?.version).toBe(1) - // expect(result.confirmation.txn.lsig?.lmsig?.subsignatures.length).toBe(3) - // expect(result.confirmation.txn.lsig?.lmsig?.subsignatures[0].signature).toBeDefined() - // expect(result.confirmation.txn.lsig?.lmsig?.subsignatures[1].signature).toBeDefined() - // expect(result.confirmation.txn.lsig?.lmsig?.subsignatures[2].signature).toBeUndefined() - // }) + test('Logicsig account lmsig signing is supported', async () => { + const { algorand, generateAccount, testAccount } = localnet.context + const account1 = await generateAccount({ initialFunds: algo(1) }) + const account2 = await generateAccount({ initialFunds: algo(1) }) + const account3 = await generateAccount({ initialFunds: algo(1) }) + + const msigParams = { + version: 1, + threshold: 2, + addrs: [account1.addr, account2.addr, account3.addr], + } + + const msigAccount1 = new MultisigAccount(msigParams, [account1]) + const msigAccount2 = new MultisigAccount(msigParams, [account2]) + + // Setup the multisig delegated logicsig + const lsigAccount = new LogicSigAccount( + Uint8Array.from([1, 32, 1, 1, 34]), // int 1 + [Uint8Array.from([1]), Uint8Array.from([2, 3])], + msigAccount1.addr, + ) + + await lsigAccount.signForDelegation(msigAccount1) // sign with the first account + await lsigAccount.signForDelegation(msigAccount2) // sign with the second account + + await localnet.algorand.account.ensureFunded(lsigAccount.address(), testAccount, algo(1)) // Fund the lsig account + + algorand.setSignerFromAccount(lsigAccount) + + const result = await algorand.send.payment({ + sender: lsigAccount.address(), + receiver: testAccount.addr, + amount: algo(0.1), + }) + + expect(result.confirmation.txn.lsig?.msig).toBeUndefined() + expect(result.confirmation.txn.lsig?.lmsig).toBeDefined() + expect(result.confirmation.txn.lsig?.lmsig?.threshold).toBe(2) + expect(result.confirmation.txn.lsig?.lmsig?.version).toBe(1) + expect(result.confirmation.txn.lsig?.lmsig?.subsigs.length).toBe(3) + expect(result.confirmation.txn.lsig?.lmsig?.subsigs[0].sig).toBeDefined() + expect(result.confirmation.txn.lsig?.lmsig?.subsigs[1].sig).toBeDefined() + expect(result.confirmation.txn.lsig?.lmsig?.subsigs[2].sig).toBeUndefined() + }) }) diff --git a/src/types/account-manager.ts b/src/types/account-manager.ts index e6627ba6e..14bbd031f 100644 --- a/src/types/account-manager.ts +++ b/src/types/account-manager.ts @@ -438,7 +438,23 @@ export class AccountManager { return nacl.sign.detached(bytesToSign, keypair.secretKey) } - return this.signerAccount(generateAddressWithSigners({ ed25519Pubkey: keypair.publicKey, rawEd25519Signer: rawSigner })) + const addrWithSigners = generateAddressWithSigners({ ed25519Pubkey: keypair.publicKey, rawEd25519Signer: rawSigner }) + + this._accounts[addrWithSigners.addr.toString()] = addrWithSigners + + const acct = addrWithSigners.addr as Address & AddressWithSigners + + for (const prop in addrWithSigners) { + // Create a new Address instance for avoid circular references + if (prop === 'addr') { + acct.addr = new Address(addrWithSigners.addr.publicKey) + continue + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(acct as any)[prop] = (addrWithSigners as any)[prop] + } + + return acct } /** diff --git a/src/types/testing.ts b/src/types/testing.ts index 30c69cc57..d86419ea5 100644 --- a/src/types/testing.ts +++ b/src/types/testing.ts @@ -1,6 +1,15 @@ import { AlgodClient } from '@algorandfoundation/algokit-algod-client' import { Address } from '@algorandfoundation/algokit-common' -import { AddressWithSigners, AddressWithTransactionSigner, LogicSigAccount, Transaction } from '@algorandfoundation/algokit-transact' +import { + AddressWithSigners, + AddressWithTransactionSigner, + DelegatedLsigSigner, + LogicSigAccount, + MxBytesSigner, + ProgramDataSigner, + Transaction, + TransactionSigner, +} from '@algorandfoundation/algokit-transact' import { MultisigAccount } from '@algorandfoundation/algokit-transact' import { IndexerClient, TransactionResponse } from '@algorandfoundation/algokit-indexer-client' import { KmdClient } from '@algorandfoundation/algokit-kmd-client' @@ -43,7 +52,18 @@ export interface GetTestAccountParams { /** Whether to suppress the log (which includes a mnemonic) or not (default: do not suppress the log) */ suppressLog?: boolean /** Optional override for how to get a test account; this allows you to retrieve accounts from a known or cached list of accounts. */ - accountGetter?: (algorand: AlgorandClient) => Promise + accountGetter?: (algorand: AlgorandClient) => Promise< + Address & + AddressWithTransactionSigner & { + account: { + addr: Readonly
+ signer: TransactionSigner + lsigSigner: DelegatedLsigSigner + programDataSigner: ProgramDataSigner + mxBytesSigner: MxBytesSigner + } + } + > } /** Configuration for creating an Algorand testing fixture. */ @@ -57,7 +77,21 @@ export interface AlgorandFixtureConfig extends Partial { /** The amount of funds to allocate to the default testing account, if not specified then it will get 10 ALGO. */ testAccountFunding?: AlgoAmount /** Optional override for how to get an account; this allows you to retrieve accounts from a known or cached list of accounts. */ - accountGetter?: (algod: AlgodClient, kmd?: KmdClient) => Promise + accountGetter?: ( + algod: AlgodClient, + kmd?: KmdClient, + ) => Promise< + Address & + AddressWithTransactionSigner & { + account: { + addr: Readonly
+ signer: TransactionSigner + lsigSigner: DelegatedLsigSigner + programDataSigner: ProgramDataSigner + mxBytesSigner: MxBytesSigner + } + } + > } /** An Algorand automated testing fixture */