Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V7 tweaks #317

Merged
merged 12 commits into from
Sep 29, 2024
Merged
14 changes: 7 additions & 7 deletions docs/capabilities/algorand-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,12 @@ The `AlgorandClient` has a number of manager class instances that help you quick

### Creating transactions

You can compose a transaction via `algorand.transactions...`, which gives you an instance of the [`AlgorandClientTransactionCreator`](../code/classes/types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md) class. Intellisense will guide you on the different options.
You can compose a transaction via `algorand.createTransaction...`, which gives you an instance of the [`AlgorandClientTransactionCreator`](../code/classes/types_algorand_client_transaction_creator.AlgorandClientTransactionCreator.md) class. Intellisense will guide you on the different options.

The signature for the calls to send a single transaction usually look like:

```
algorand.transactions.{method}(params: {ComposerTransactionTypeParams} & CommonTransactionParams): Promise<Transaction>
algorand.createTransaction.{method}(params: {ComposerTransactionTypeParams} & CommonTransactionParams): Promise<Transaction>
```

- To get intellisense on the params, open an object parenthesis (`{`) and use your IDE's intellisense keyboard shortcut (e.g. ctrl+space).
Expand All @@ -70,7 +70,7 @@ algorand.transactions.{method}(params: {ComposerTransactionTypeParams} & CommonT
The return type for the ABI method call methods are slightly different:

```
algorand.transactions.app{callType}MethodCall(params: {ComposerTransactionTypeParams} & CommonTransactionParams): Promise<BuiltTransactions>
algorand.createTransaction.app{callType}MethodCall(params: {ComposerTransactionTypeParams} & CommonTransactionParams): Promise<BuiltTransactions>
```

Where `BuiltTransactions` looks like this:
Expand Down Expand Up @@ -100,12 +100,12 @@ Further documentation is present in the related capabilities:

The signature for the calls to send a single transaction usually look like:

`algorand.send.{method}(params: {ComposerTransactionTypeParams} & CommonAppCallParams & ExecuteParams): SingleSendTransactionResult`
`algorand.send.{method}(params: {ComposerTransactionTypeParams} & CommonAppCallParams & SendParams): SingleSendTransactionResult`

- To get intellisense on the params, open an object parenthesis (`{`) and use your IDE's intellisense keyboard shortcut (e.g. ctrl+space).
- `{ComposerTransactionTypeParams}` will be the parameters that are specific to that transaction type e.g. `PaymentParams`, [see the full list](../code/modules/types_composer.md#type-aliases)
- [`CommonAppCallParams`](../code/modules/types_composer.md#commonappcallparams) are the [common app call transaction parameters](./app.md#common-app-parameters) that can be specified for every single app transaction
- [`ExecuteParams`](../code/interfaces/types_transaction.ExecuteParams.md) are the [parameters](#transaction-parameters) that control execution semantics when sending transactions to the network
- [`SendParams`](../code/interfaces/types_transaction.SendParams.md) are the [parameters](#transaction-parameters) that control execution semantics when sending transactions to the network
- [`SendSingleTransactionResult`](../code/modules/types_algorand_client.md#sendsingletransactionresult) is all of the information that is relevant when [sending a single transaction to the network](./transaction.md#sending-a-transaction)

Generally, the functions to immediately send a single transaction will emit log messages before and/or after sending the transaction. You can opt-out of this by sending `suppressLog: true`.
Expand All @@ -119,7 +119,7 @@ const result = algorand
.newGroup()
.addPayment({ sender: 'SENDERADDRESS', receiver: 'RECEIVERADDRESS', amount: (1).microAlgo() })
.addAssetOptIn({ sender: 'SENDERADDRESS', assetId: 12345n })
.execute()
.send()
```

`newGroup()` returns a new [`AlgoKitComposer`](./algokit-composer.md) instance, which can also return the group of transactions, simulate them and other things.
Expand All @@ -144,7 +144,7 @@ There are two common base interfaces that get reused:
- `validityWindow?: number` - How many rounds the transaction should be valid for, if not specified then the registered default validity window will be used.
- `firstValidRound?: bigint` - Set the first round this transaction is valid. If left undefined, the value from algod will be used. We recommend you only set this when you intentionally want this to be some time in the future.
- `lastValidRound?: bigint` - The last round this transaction is valid. It is recommended to use `validityWindow` instead.
- [`ExecuteParams`](../code/interfaces/types_transaction.ExecuteParams.md)
- [`SendParams`](../code/interfaces/types_transaction.SendParams.md)
- `maxRoundsToWaitForConfirmation?: number` - The number of rounds to wait for confirmation. By default until the latest lastValid has past.
- `suppressLog?: boolean` - Whether to suppress log messages from transaction send, default: do not suppress.

Expand Down
82 changes: 43 additions & 39 deletions docs/capabilities/app-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,20 @@ As well as allowing you to control creation and deployment of apps, the `AppFact
This is possible via two methods on the app factory:

- [`factory.getAppClientById(params)`](../code/classes/types_app_factory.AppFactory.md#getappclientbyid) - Returns a new `AppClient` client for an app instance of the given ID. Automatically populates appName, defaultSender and source maps from the factory if not specified in the params.
- [`factory.getAppClientByCreatorAddressAndName(params)`](../code/classes/types_app_factory.AppFactory.md#getappclientbycreatoraddressandname) - Returns a new `AppClient` client, resolving the app by creator address and name using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). Automatically populates appName, defaultSender and source maps from the factory if not specified in the params.
- [`factory.getAppClientByCreatorAndName(params)`](../code/classes/types_app_factory.AppFactory.md#getappclientbycreatorandname) - Returns a new `AppClient` client, resolving the app by creator address and name using AlgoKit app deployment semantics (i.e. looking for the app creation transaction note). Automatically populates appName, defaultSender and source maps from the factory if not specified in the params.

```typescript
const app1 = factory.getAppClientById({ appId: 12345n })
const app2 = factory.getAppClientById({ appId: 12346n })
const app3 = factory.getAppClientById({ appId: 12345n, defaultSender: 'SENDER2ADDRESS' })
const app4 = factory.getAppClientByCreatorAddressAndName({
const appClient1 = factory.getAppClientById({ appId: 12345n })
const appClient2 = factory.getAppClientById({ appId: 12346n })
const appClient3 = factory.getAppClientById({ appId: 12345n, defaultSender: 'SENDER2ADDRESS' })
const appClient4 = factory.getAppClientByCreatorAndName({
creatorAddress: 'CREATORADDRESS',
})
const app5 = factory.getAppClientByCreatorAddressAndName({
const appClient5 = factory.getAppClientByCreatorAndName({
creatorAddress: 'CREATORADDRESS',
appName: 'NonDefaultAppName',
})
const app6 = factory.getAppClientByCreatorAddressAndName({
const appClient6 = factory.getAppClientByCreatorAndName({
creatorAddress: 'CREATORADDRESS',
appName: 'NonDefaultAppName',
ignoreCache: true, // Perform fresh indexer lookups
Expand All @@ -108,9 +108,9 @@ The create method is a wrapper over the `appCreate` (bare calls) and `appCreateM

```typescript
// Use no-argument bare-call
const { result, app } = factory.create()
const { result, appClient } = factory.send.bare.create()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SilentRhetoric even though it adds a little bit of verbosity we made the decision that every time a transaction is sent to the network you will see the word send (apart from the deploy call, but that's a special case since it may or may not send transactions and is a higher-order function).

As part of this we renamed execute to send (with a backwards compatible @deprecate) in AlgoKitComposer and renamed ExecuteParams to SendParams.

// Specify parameters for bare-call and override other parameters
const { result, app } = factory.create({
const { result, appClient } = factory.send.bare.create({
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also settled on appClient over app to meet your principle of clear, explicit naming @SilentRhetoric

args: [new Uint8Array(1, 2, 3, 4)],
staticFee: (3000).microAlgo(),
onComplete: algosdk.OnApplicationComplete.OptIn,
Expand All @@ -123,13 +123,13 @@ const { result, app } = factory.create({
populateAppCallResources: true,
})
// Specify parameters for ABI method call
const { result, app } = factory.create({
const { result, appClient } = factory.send.create({
method: 'create_application',
args: [1, 'something'],
})
```

If you want to construct a custom create call, use the underlying [`algorand.send.appCreate` / `algorand.transactions.appCreate` / `algorand.send.appCreateMethodCall` / `algorand.transactions.appCreateMethodCall` methods](./app.md#creation) then you can get params objects:
If you want to construct a custom create call, use the underlying [`algorand.send.appCreate` / `algorand.createTransaction.appCreate` / `algorand.send.appCreateMethodCall` / `algorand.createTransaction.appCreateMethodCall` methods](./app.md#creation) then you can get params objects:
Copy link
Contributor Author

@robdmoore robdmoore Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SilentRhetoric transactions -> createTransaction to get the verb plus the consistency of singular rather than plural.

We didn't rename params because the correct name would be getTransactionParams and it's simply too verbose and the places you are most likely to use params are inline when nesting ABI method arguments where you want less verbosity. As such we updated the jsdoc comment to make it more obvious how it's used and feel it's one that people will follow examples to understand how to use (and honestly, it's a slightly more advanced use case anyway so I think it's OK if it's a bit less discoverable).


- `factory.params.create(params)` - ABI method create call for deploy method or an underlying [`appCreateMethodCall` call](./app.md#creation)
- `factory.params.bare.create(params)` - Bare create call for deploy method or an underlying [`appCreate` call](./app.md#creation)
Expand All @@ -150,9 +150,9 @@ The deploy method is a wrapper over the [`AppDeployer`'s `deploy` method](./app-
```typescript
// Use no-argument bare-calls to deploy with default behaviour
// for when update or schema break detected (fail the deployment)
const { result, app } = factory.deploy({})
const { result, appClient } = factory.deploy({})
// Specify parameters for bare-calls and override the schema break behaviour
const { result, app } = factory.deploy({
const { result, appClient } = factory.deploy({
createParams: {
args: [new Uint8Array(1, 2, 3, 4)],
staticFee: (3000).microAlgo(),
Expand All @@ -174,7 +174,7 @@ const { result, app } = factory.deploy({
deletable: true,
})
// Specify parameters for ABI method calls
const { result, app } = factory.deploy({
const { result, appClient } = factory.deploy({
createParams: {
method: "create_application",
args: [1, "something"],
Expand Down Expand Up @@ -210,8 +210,8 @@ This is done via the following properties:

- `appClient.params.{onComplete}(params)` - Params for an ABI method call
- `appClient.params.bare.{onComplete}(params)` - Params for a bare call
- `appClient.transactions.{onComplete}(params)` - Transaction(s) for an ABI method call
- `appClient.transactions.bare.{onComplete}(params)` - Transaction for a bare call
- `appClient.createTransaction.{onComplete}(params)` - Transaction(s) for an ABI method call
- `appClient.createTransaction.bare.{onComplete}(params)` - Transaction for a bare call
- `appClient.send.{onComplete}(params)` - Sign and send an ABI method call
- `appClient.send.bare.{onComplete}(params)` - Sign and send a bare call

Expand All @@ -229,23 +229,23 @@ The input payload for all of these calls is the same as the [underlying app meth
The return payload for all of these is the same as the [underlying methods](./app.md#calling-apps).

```typescript
const call1 = await app.send.update({
const call1 = await appClient.send.update({
method: 'update_abi',
args: ['string_io'],
deployTimeParams,
})
const call2 = await app.send.delete({
const call2 = await appClient.send.delete({
method: 'delete_abi',
args: ['string_io'],
})
const call3 = await app.send.optIn({ method: 'opt_in' })
const call4 = await app.send.bare.clearState()
const call3 = await appClient.send.optIn({ method: 'opt_in' })
const call4 = await appClient.send.bare.clearState()

const transaction = await app.transactions.bare.closeOut({
const transaction = await appClient.createTransaction.bare.closeOut({
args: [new Uint8Array(1, 2, 3)],
})

const params = app.params.optIn({ method: 'optin' })
const params = appClient.params.optIn({ method: 'optin' })
```

## Funding the app account
Expand All @@ -259,18 +259,18 @@ The input parameters are:
Note: If you are passing the funding payment in as an ABI argument so it can be validated by the ABI method then you'll want to get the funding call as a transaction, e.g.:

```typescript
const result = await app.send.call({
const result = await appClient.send.call({
method: 'bootstrap',
args: [
app.transactions.fundAppAccount({
appClient.createTransaction.fundAppAccount({
amount: microAlgo(200_000),
}),
],
boxReferences: ['Box1'],
})
```

You can also get the funding call as a params object via `app.params.fundAppAccount(params)`.
You can also get the funding call as a params object via `appClient.params.fundAppAccount(params)`.

## Reading state

Expand All @@ -282,9 +282,9 @@ The ARC-56 app spec can specify detailed information about the encoding format o

You can access this functionality via:

- `app.state.global.{method}()` - Global state
- `app.state.local(address).{method}()` - Local state
- `app.state.box.{method}()` - Box storage
- `appClient.state.global.{method}()` - Global state
- `appClient.state.local(address).{method}()` - Local state
- `appClient.state.box.{method}()` - Box storage

Where `{method}` is one of:

Expand All @@ -294,10 +294,10 @@ Where `{method}` is one of:
- `getMap(mapName)` - Returns all map values for the given map in a key=>value record. It's recommended that this is only done when you have a unique `prefix` for the map otherwise there's a high risk that incorrect values will be included in the map.

```typescript
const values = app.state.global.getAll()
const value = app.state.local('ADDRESS').getValue('value1')
const mapValue = app.state.box.getMapValue('map1', 'mapKey')
const map = app.state.global.getMap('myMap')
const values = appClient.state.global.getAll()
const value = appClient.state.local('ADDRESS').getValue('value1')
const mapValue = appClient.state.box.getMapValue('map1', 'mapKey')
const map = appClient.state.global.getMap('myMap')
```

### Generic methods
Expand All @@ -313,17 +313,17 @@ There are various methods defined that let you read state from the smart contrac
- `getBoxValuesFromABIType(type, filter)` - Gets the current values of the boxes from an ABI type using [`algorand.app.getBoxValuesFromABIType`](./app.md#boxes)

```typescript
const globalState = await app.getGlobalState()
const localState = await app.getLocalState('ACCOUNTADDRESS')
const globalState = await appClient.getGlobalState()
const localState = await appClient.getLocalState('ACCOUNTADDRESS')

const boxName: BoxReference = 'my-box'
const boxName2: BoxReference = 'my-box2'

const boxNames = app.getBoxNames()
const boxValue = app.getBoxValue(boxName)
const boxValues = app.getBoxValues([boxName, boxName2])
const boxABIValue = app.getBoxValueFromABIType(boxName, algosdk.ABIStringType)
const boxABIValues = app.getBoxValuesFromABIType([boxName, boxName2], algosdk.ABIStringType)
const boxNames = appClient.getBoxNames()
const boxValue = appClient.getBoxValue(boxName)
const boxValues = appClient.getBoxValues([boxName, boxName2])
const boxABIValue = appClient.getBoxValueFromABIType(boxName, algosdk.ABIStringType)
const boxABIValues = appClient.getBoxValuesFromABIType([boxName, boxName2], algosdk.ABIStringType)
```

## Handling logic errors and diagnosing errors
Expand Down Expand Up @@ -364,3 +364,7 @@ Config.configure({ debug: true })
If you do that then the exception will have the `traces` property within the underlying exception will have key information from the simulation within it and this will get populated into the `led.traces` property of the thrown error.

When this debug flag is set, it will also emit debugging symbols to allow break-point debugging of the calls if the [project root is also configured](./debugging.md).

## Default arguments

If an ABI method call specifies default argument values for any of its arguments you can pass in `undefined` for the value of that argument for the default value to be automatically populated.
6 changes: 2 additions & 4 deletions docs/capabilities/app-deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,7 @@ const deploymentResult = algorand.appDeployer.deploy({
// How to handle a contract code update
onUpdate: OnUpdate.Update,
// Optional execution control parameters
executeParams: {
populateAppCallResources: true,
},
populateAppCallResources: true,
})
```

Expand All @@ -229,9 +227,9 @@ The first parameter `deployment` is an [`AppDeployParams`](../code/interfaces/ty
- [`TealTemplateParams`](../code/interfaces/types_app.TealTemplateParams.md) is a `key => value` object that will result in `TMPL_{key}` being replaced with `value` (where a string or `Uint8Array` will be appropriately encoded as bytes within the TEAL code)
- `onSchemaBreak?: 'replace' | 'fail' | 'append' | OnSchemaBreak` - determines [what should happen](../code/enums/types_app.OnSchemaBreak.md) if a breaking change to the schema is detected (e.g. if you need more global or local state that was previously requested when the contract was originally created)
- `onUpdate?: 'update' | 'replace' | 'fail' | 'append' | OnUpdate` - determines [what should happen](../code/enums/types_app.OnUpdate.md) if an update to the smart contract is detected (e.g. the TEAL code has changed since last deployment)
- `executeParams?: ExecuteParams` - [transaction execution control parameters](./algorand-client.md#transaction-parameters)
- `existingDeployments?: AppLookup` - optionally allows the [app lookup retrieval](#lookup-deployed-apps-by-name) to be skipped if it's already been retrieved outside of this `AppDeployer` instance
- `ignoreCache?: boolean` - optionally allows the [lookup cache](#lookup-deployed-apps-by-name) to be ignored and force retrieval of fresh deployment metadata from indexer
- Everything from [`SendParams`](../code/interfaces/types_transaction.SendParams.md) - [transaction execution control parameters](./algorand-client.md#transaction-parameters)

### Idempotency

Expand Down
Loading
Loading