All skills

Guide for writing TypeScript code with AlgoKit Utils (`@algorandfoundation/algokit-utils`). Use this skill whenever the user is building on Algorand with TypeScript — client setup, account management, payments, asset operations, atomic transaction groups, smart contract deployment and interaction (AppFactory, AppClient, ARC-56/ARC-32 specs), raw app calls, key registration, network management, testing with algorandFixture, error handling, and the low-level crypto primitives under `@algorandfoundation/algokit-utils/crypto` (Ed25519 keygen/signing/verification, SHA-512/256 `hash`, Peikert xHD BIP44 wallets, wrapped-secret patterns). Trigger on imports from `@algorandfoundation/algokit-utils` (incl. `/crypto`, `/testing`, `/transact` subpaths), references to `AlgorandClient`, `AppFactory`, `AppClient`, `AlgoAmount`, `algorandFixture`, `ed25519Generator`, `peikertXHdWalletGenerator`, `hash`, `WrappedEd25519Seed`, or `RawEd25519Signer`. Also on any TypeScript or JavaScript code that builds on Algorand.

Use this Skill: https://skilld.dev/gh/algorand-devrel/algorand-agent-skills/algokit-utils-ts

This session only. Nothing lands on disk.

referencestransaction-composition.md

≈1.2k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Transaction composition (atomic groups)

Create a transaction group

Start composing an atomic group of transactions.

import { AlgorandClient } from "@algorandfoundation/algokit-utils";

const algorand = AlgorandClient.defaultLocalNet();

const composer = algorand.newGroup();

What just happened? algorand.newGroup() created a new TransactionComposer instance. Every transaction you add to this composer will be submitted as a single atomic group — they all succeed together or all fail together.

Add multiple transactions to a group

Combine a payment and an asset transfer into one atomic group.

const sender = algorand.account.random();
const receiver = algorand.account.random();

const result = await algorand
  .newGroup()
  .addPayment({
    sender: sender.addr,
    receiver: receiver.addr,
    amount: (1).algo(),
  })
  .addAssetTransfer({
    sender: sender.addr,
    receiver: receiver.addr,
    assetId: 12345n,
    amount: 100n,
  })
  .send();

console.log(`Group ID: ${result.groupId}`);
console.log(`Transaction IDs: ${result.txIds.join(", ")}`);

What just happened? The addPayment() and addAssetTransfer() calls return the composer for fluent chaining. When you call .send(), both transactions are grouped, signed, and submitted atomically — the payment and asset transfer either both confirm or both fail.

Build and send an atomic group

Build the group to inspect transactions before sending.

const composer = algorand
  .newGroup()
  .addPayment({
    sender: sender.addr,
    receiver: receiver.addr,
    amount: (1).algo(),
  })
  .addPayment({
    sender: sender.addr,
    receiver: receiver.addr,
    amount: (2).algo(),
  });

// Build to inspect the transactions
const built = await composer.build();
console.log(`Group contains ${built.transactions.length} transactions`);

// Then send the built group
const result = await composer.send();
console.log(`Confirmed in round: ${result.confirmations[0].confirmedRound}`);

What just happened? Calling .build() composes and returns the transaction group with signers attached, letting you inspect the transactions before committing. A subsequent .send() signs and submits the already-built group.

Simulate a transaction group before sending

Dry-run a group to check for errors without spending Algo.

const composer = algorand.newGroup().addPayment({
  sender: sender.addr,
  receiver: receiver.addr,
  amount: (5).algo(),
});

// Simulate without requiring real signatures
const simResult = await composer.simulate({ skipSignatures: true });

console.log(`Would succeed: ${simResult.confirmations.length > 0}`);
console.log(`Simulated round: ${simResult.simulateResponse.lastRound}`);

What just happened? .simulate({ skipSignatures: true }) sends the group to the node's simulate endpoint, which evaluates it without real signatures or on-chain effects. The result includes a simulateResponse with detailed execution info. This is useful for validating logic, checking opcode budgets, and estimating fees before sending real transactions.

Set fees on grouped transactions

Control fees at the per-transaction level within a group.

const result = await algorand
  .newGroup()
  .addPayment({
    sender: sender.addr,
    receiver: receiver.addr,
    amount: (1).algo(),
    // This transaction covers extra fee for an inner transaction
    extraFee: (1000).microAlgo(),
  })
  .addPayment({
    sender: sender.addr,
    receiver: receiver.addr,
    amount: (2).algo(),
    // Cap the fee to prevent overspending
    maxFee: (3000).microAlgo(),
  })
  .send();

What just happened? Fee control is set per transaction, not per group. extraFee adds to the network-suggested fee (useful when a transaction triggers inner transactions that need fee coverage), and maxFee throws an error if the calculated fee exceeds the cap — protecting you from overspending during congestion.

Clone a composer for reuse

Duplicate a composer so you can send the same group template multiple times.

const template = algorand.newGroup().addPayment({
  sender: sender.addr,
  receiver: receiver.addr,
  amount: (1).algo(),
});

// Clone creates an independent copy with the same transactions
const copy = template.clone();

// Send the clone — the original is unaffected and can be cloned again
const result = await copy.send();
console.log(`Sent from clone: ${result.txIds[0]}`);

What just happened? .clone() creates a deep copy of the composer, including all queued transactions. The original and the clone are fully independent — you can modify or send one without affecting the other. This is handy for reusable transaction templates.

Source: SKILL.md on GitHub

1 alert1mo3 checks · Risk SAFE
  • Gen Agent Trust Hub1mo

    The skill provides a comprehensive guide for using the AlgoKit Utils TypeScript library. It follows security best practices, such as recommending environment variables for secrets, and uses standard testing mnemonics and placeholder domains in its code examples. No malicious patterns or security risks were detected.

  • Socket1mo

    No alerts

  • Snyk1mo

    Risk: HIGH · 2 issues

Signed by skilld at 4235fb8. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 weeks ago.

Activeupdated 6 months ago

README badge

README badge for algorand-devrel/algorand-agent-skills/algokit-utils-ts