# Send a Transaction

Transactions are made up of one or more [operations](https://docs.keeta.com/components/blocks/operations). Operations describe the specific actions your account wants to perform on the ledger — for example, sending tokens, setting permissions, or interacting with storage.

Each operation is made up of **effects**, which are the actual changes applied to the [ledger](https://docs.keeta.com/components/ledger).

Take the `send` operation, for example:

* It **decreases** the balance of the sender
* It **increases** the balance of the recipient
* It **validates** that the sender's balance doesn't drop below zero

When you build a transaction, you're queuing up one or more of these operations to execute together. The KeetaNet SDK gives you tools to construct, compute, and publish these operations easily.

{% hint style="info" %}
You can think of a transaction as a container for operations, and operations as instructions to update the blockchain state.
{% endhint %}

For a full list of available operations, check out the our [static documentation section](https://static.test.keeta.com/docs/classes/KeetaNetSDK.Referenced.BlockOperation.html).

## Code Example: Sending 1 KTA

{% hint style="info" %}

#### When running this code, make sure that the account has at least 1 KTA in the account

{% endhint %}

```typescript
/**
 * Load the KeetaNet Client SDK
 */
const KeetaNet = require('@keetanetwork/keetanet-client');

/**
 * This is the fake seed for the demo account, replace with a valid one
 */
const DEMO_ACCOUNT_SEED = 'D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0D3M0';

async function main() {
	// Create a signer account from the demo seed (account index 0)
	const signer_account = KeetaNet.lib.Account.fromSeed(DEMO_ACCOUNT_SEED, 0);
	console.log('🔑 Signer account:', signer_account.publicKeyString.get());

	// Connect to the Keeta test network
	const client = KeetaNet.UserClient.fromNetwork('test', signer_account);

	// Start building a transaction
	const builder = client.initBuilder();

	// Define the recipient (the faucet address for testing)
	const faucet_account = KeetaNet.lib.Account.fromPublicKeyString(
		'keeta_aabszsbrqppriqddrkptq5awubshpq3cgsoi4rc624xm6phdt74vo5w7wipwtmi'
	);

	// Add a send operation to the builder: 1 KTA to the faucet address
	builder.send(faucet_account, 1n, client.baseToken);

	// Compute the transaction blocks (Keeta breaks operations into blocks)
	const computed = await client.computeBuilderBlocks(builder);
	console.log('🧱 Computed blocks:', computed.blocks);

	// Publish the transaction to the network
	const transaction = await client.publishBuilder(builder);
	console.log('✅ Transaction published:', transaction);
}

main().then(
	() => process.exit(0),
	(err) => {
		console.error('❌ Error:', err);
		process.exit(1);
	}
);

```

#### What's Happening Here?

* You **create a signer** using the account derived from your seed.
* You connect to the **Keeta testnet** using `UserClient`.
* You initialize a **transaction builder**, which lets you queue operations.
* You queue a `send` operation with 1 KTA as the amount.
* You compute the transaction blocks (how Keeta structures data before publishing).
* You publish the transaction to the network.
