> ## Documentation Index
> Fetch the complete documentation index at: https://developers.stellar.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Issue an Asset Tutorial

> Learn how to issue a Stellar asset, set trustlines, and manage supply. Follow this step-by-step guide to create and distribute assets on the network.

In this tutorial, we will walk through the steps to issue an asset on the Stellar test network.

> [!NOTE]
>
> If you'd like to interact with an asset issued on the Stellar network in smart contracts, you can create or deploy the [Stellar Asset Contract](/docs/tokens/stellar-asset-contract.md) for that asset.

## Prerequisites

You must ensure you have the required amount of XLM to create your issuing and distribution accounts and cover the minimum balance and transaction fees. If you’re issuing an asset on the testnet, you can fund your account by getting test XLM from friendbot. If you’re issuing an asset in production, you will need to acquire XLM from another wallet or exchange.

If you’d like to avoid your users having to deal with transaction fees, consider using fee-bump transactions. Read more in our [Fee-Bump Transaction Guide](/docs/build/guides/transactions/fee-bump-transactions.md).

Learn about the testnet and mainnet in our [Networks section](/docs/networks.md).

Learn more about fees in our [Fees, Resource Limits, and Metering section](/docs/learn/fundamentals/fees-resource-limits-metering.md).

## Foundational tools

### Issuer account keypair

First, you must generate a unique keypair. The public key will act as your [issuing identity](/docs/learn/fundamentals/stellar-data-structures/assets.md#issuer) on the network, while you use the secret key to sign transactions.

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const issuerKeypair = StellarSdk.Keypair.random();

console.log("Issuer Public Key:", issuerKeypair.publicKey());
console.log("Issuer Secret Key:", issuerKeypair.secret());
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from stellar_sdk import Keypair

issuer_keypair = Keypair.random()

print("Issuer Public Key:", issuer_keypair.public_key)
print("Issuer Secret Key:", issuer_keypair.secret)
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
KeyPair issuerKeypair = KeyPair.random();

System.out.println("Issuer Public Key: " + issuerKeypair.getAccountId());
System.out.println("Issuer Secret Key: " + issuerKeypair.getSecretSeed());
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
import (
  "github.com/stellar/go-stellar-sdk/keypair"
  "fmt"
)

issuerKeypair := keypair.MustRandom()

fmt.Println("Issuer Public Key:", issuerKeypair.Address())
fmt.Println("Issuer Secret Key:", issuerKeypair.Seed())
```

> [!NOTE]
>
> Your account address will not change once you issue your asset, even if you modify its [signers](/docs/learn/fundamentals/transactions/signatures-multisig.md). Many issuers employ [vanity public keys](https://github.com/JFWooten4/stellar-vanity-toolkit) related to their asset. For instance, you might configure a custom signer in [base32](/docs/learn/glossary.md#account-id) like `GASTRO...USD`.

> [!NOTE]
>
> Many users secure their issuing account with cold storage techniques, such as a hardware wallet or multisignature setup. This adds an extra layer of protection by keeping your secret key offline or requiring multiple approvals for transactions.

### Distribution account keypair

Your asset can be issued and transferred between accounts through a payment, contract, or claimable balance. Although it is not required to create a distribution account, it is best practice, so we will do so in this example. Read more in our [Issuing and Distribution Accounts section](/docs/tokens/control-asset-access.md#issuing-and-distribution-accounts).

#### Three Operations

##### Generate a new keypair

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const distributorKeypair = StellarSdk.Keypair.random();
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
distributor_keypair = Keypair.random()
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
KeyPair distributorKeypair = KeyPair.random();
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
distributorKeypair := keypair.MustRandom()
```

##### Import an existing keypair

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const distributorKeypair = StellarSdk.Keypair.fromSecret(‘SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4’)
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
distributor_keypair = Keypair.from_secret("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4")
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
KeyPair distributorKeypair = KeyPair.fromSecretSeed("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4");
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
distributorKeypair := keypair.MustParseFull("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4")
```

##### Employ [multiple signatures](/docs/learn/fundamentals/transactions/signatures-multisig.md)

> [!CAUTION]
>
> Be careful when working with raw secret keys. If you don't have issuer trustline [clawback](/docs/build/guides/transactions/clawbacks.md) enabled, any misstep here could permanently render assets lost. Many users put their first few projects on [testnet](/docs/networks.md#testnet) or try out [Quests](/docs/learn/interactive/quest.md) which provide a low-stakes introductory sandbox.

### Local asset object

The asset object is a combination of your [code](/docs/tokens/control-asset-access.md#naming-an-asset) and your issuing public key. After your issuance, anyone can search the network for your unique asset.

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const astroDollar = new StellarSdk.Asset(
  "AstroDollar",
  issuerKeypair.publicKey(),
);
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from stellar_sdk import Keypair, Asset

astro_dollar = Asset("AstroDollar", issuer_keypair.public_key)
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
Asset astroDollar = Asset.createNonNativeAsset("AstroDollar", issuerKeypair.getAccountId());
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
import (
  "github.com/stellar/go-stellar-sdk/keypair"
  "github.com/stellar/go-stellar-sdk/txnbuild"
)

astroDollar := txnbuild.CreditAsset{Code: "AstroDollar", Issuer: issuerKeypair.Address()}
```

> [!NOTE]
>
> While anyone can create an asset, there may be real-world [compliance](/docs/tokens/anatomy-of-an-asset.md#compliance) implications relevant to your use case.

> [!NOTE]
>
> You’ll want to make sure you publish information about your asset to establish trust with your users and prevent errors. Learn how to do so with our [Publish Information About Your Asset section](/docs/tokens/publishing-asset-info.md).

## Network transactions

These examples read accounts from and submit transactions to [Stellar RPC](../data/apis/rpc). RPC takes a transaction and answers immediately with the status `PENDING`, so you then poll for the final result. See [sendTransaction](/docs/data/apis/rpc/api-reference/methods/sendTransaction.md) and [getTransaction](/docs/data/apis/rpc/api-reference/methods/getTransaction.md).

### Build transaction to establish distributor trustline

Accounts must establish a [trustline](/docs/learn/fundamentals/stellar-data-structures/accounts.md#trustlines) with the issuing account to hold that issuer’s asset. This is true for all assets except for the network’s native token, [Lumens](/docs/learn/fundamentals/lumens.md).

> [!NOTE]
>
> If you’d like to avoid your users having to deal with trustlines or XLM, consider using sponsored reserves. Read more in our [Sponsored Reserves guide](/docs/build/guides/transactions/sponsored-reserves.md).

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const StellarSdk = require("@stellar/stellar-sdk");
const server = new StellarSdk.rpc.Server("https://soroban-testnet.stellar.org");
const account = await server.getAccount(distributorKeypair.publicKey());

// This step only builds the transaction.  It still needs to be signed.
const transaction = new StellarSdk.TransactionBuilder(account, {
  fee: StellarSdk.BASE_FEE,
  networkPassphrase: StellarSdk.Networks.TESTNET,
})
  // The `changeTrust` operation creates (or alters) a trustline
  .addOperation(
    StellarSdk.Operation.changeTrust({
      asset: astroDollar,
      limit: "1000", // optional
      source: distributorKeypair.publicKey(),
    }),
  )
  .setTimeout(100)
  .build();
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from stellar_sdk import Keypair, Asset, Network, SorobanServer, TransactionBuilder

server = SorobanServer("https://soroban-testnet.stellar.org")
distributor_account = server.load_account(distributor_keypair.public_key)

transaction = (
  TransactionBuilder(
    source_account=distributor_account,
    network_passphrase=Network.TESTNET_NETWORK_PASSPHRASE,
    base_fee=100
  )
  .append_change_trust_op(asset=astro_dollar, limit="1000")
  .set_timeout(100)
  .build()
)
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
SorobanServer server = new SorobanServer("https://soroban-testnet.stellar.org");
TransactionBuilderAccount distributorAccount = server.getAccount(distributorKeypair.getAccountId());

Transaction transaction = new TransactionBuilder(distributorAccount, Network.TESTNET)
  .addOperation(
    ChangeTrustOperation.builder()
    .asset(new ChangeTrustAsset(astroDollar))
    .limit(new BigDecimal("1000"))
    .sourceAccount(distributorKeypair.getAccountId())
    .build()
  )
  .setBaseFee(Transaction.MIN_BASE_FEE)
  .setTimeout(100)
  .build();
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
import (
  "context"

  "github.com/stellar/go-stellar-sdk/clients/rpcclient"
  "github.com/stellar/go-stellar-sdk/keypair"
  "github.com/stellar/go-stellar-sdk/network"
  "github.com/stellar/go-stellar-sdk/txnbuild"
)

ctx := context.Background()
client := rpcclient.NewClient("https://soroban-testnet.stellar.org", nil)
distributorAccount, _ := client.LoadAccount(ctx, distributorKeypair.Address())

transaction, _ := txnbuild.NewTransaction(
  txnbuild.TransactionParams{
    SourceAccount:        distributorAccount,
    IncrementSequenceNum: true,
    BaseFee:              txnbuild.MinBaseFee,
    Operations: []txnbuild.Operation{
      &txnbuild.ChangeTrust{
        Line:  astroDollar.MustToChangeTrustAsset(),
        Limit: "1000",
      },
    },
    Timebounds: txnbuild.NewInfiniteTimeout(),
  },
)
```

### Issuer payment to distributor

Payments are the most popular operation to actually issue (or mint) your asset, compared to [other issuances](/docs/learn/fundamentals/transactions/list-of-operations.md#path-payment-strict-send). A payment creates the amount of an asset specified, up to [the maximum 64-bit integer](/docs/learn/fundamentals/stellar-data-structures/assets.md#amount-precision). Relevantly, you do not need to scale up the issuing amount of your asset by the XDR [minimum increment](/docs/learn/fundamentals/stellar-data-structures/assets.md#amount-precision).

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
// We're using TransactionBuilder(...) as a short-hand here
// to show that these operations can be "chained" together.
const transaction = new StellarSdk.TransactionBuilder(...)
  // The `payment` operation sends the `amount` of the specified
  // `asset` to our distributor account
  .addOperation(StellarSdk.Operation.payment({
    destination: distributorKeypair.publicKey(),
    asset: astroDollar,
    amount: '1000',
    source: issuerKeypair.publicKey()
  }))
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
# We're using TransactionBuilder(...) as a short-hand here
# to show that these operations can be "chained" together.
transaction = (
  TransactionBuilder(...)
  .append_payment_op(
    destination=distributor_keypair.public_key,
    asset=astro_dollar,
    amount="1000"
  )
)
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
// We're using TransactionBuilder(...) as a short-hand here
// to show that these operations can be "chained" together.
Transaction transaction = new TransactionBuilder(...)
  .addOperation(PaymentOperation.builder()
    .destination(distributorKeypair.getAccountId())
    .asset(astroDollar)
    .amount(new BigDecimal("1000"))
    .sourceAccount(issuerKeypair.getAccountId())
    .build())
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
// We're using TransactionBuilder(...) as a short-hand here
// to show that these operations can be "chained" together.
transaction, _ := txnbuild.NewTransaction(
  txnbuild.TransactionParams{
    SourceAccount:        issuerAccount,
    IncrementSequenceNum: true,
    BaseFee:              txnbuild.MinBaseFee,
    Operations: []txnbuild.Operation{
      &txnbuild.Payment{
        Destination: distributorKeypair.Address(),
        Amount:      "1000",
        Asset:       astroDollar,
      },
    },
    Timebounds: txnbuild.NewInfiniteTimeout(),
  },
)
```

> [!NOTE]
>
> You can also create a market directly from the issuing account and issue tokens via trading.

### Optional transactions

#### Configure maximum supply

> [!CAUTION]
>
> This section details how to lock your account with the purpose of limiting the supply of your issued asset. However, locking your account means you’ll never be able to do anything with it ever again—whether that’s adjusting signers, changing the home domain, claiming any held XLM, or any other operation. Your account will be completely frozen.

You can permanently configure the exact number of an asset that will ever exist. Learn more about asset supply in our section on [Limiting the Supply of an Asset](/docs/tokens/control-asset-access.md#limiting-the-supply-of-an-asset)

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const lockAccountTransaction = new StellarSdk.TransactionBuilder(...)
  // This `setOptions` operation locks the issuer account
  // so there can never be any more of the asset minted
  .addOperation(StellarSdk.Operation.setOptions({
    masterWeight: 0,
    source: issuerKeypair.publicKey()
  }))
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
lock_account_transaction = (
  TransactionBuilder(...)
  .append_set_options_op(master_weight=0)
)
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
Transaction lockAccountTransaction = new TransactionBuilder(...)
  .addOperation(SetOptionsOperation.builder()
    .masterKeyWeight(0)
    .sourceAccount(issuerKeypair.getAccountId())
    .build()
  )
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
lockAccountTransaction, _ := txnbuild.NewTransaction(
  txnbuild.TransactionParams{
    SourceAccount:        issuerAccount,
    IncrementSequenceNum: true,
    BaseFee:              txnbuild.MinBaseFee,
    Operations: []txnbuild.Operation{
      &txnbuild.SetOptions{
        MasterWeight: txnbuild.NewThreshold(0),
      },
    },
    Timebounds: txnbuild.NewInfiniteTimeout(),
  },
)
```

#### Approve distributor trustline

If you enable the [authorization flag](/docs/tokens/control-asset-access.md#authorization-required-0x1), the issuing account also needs to approve the distributor account's trustline request before the issuing payment. You will need to do this for all new accounts when set for your asset.

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
const issuingAccount = await server.getAccount(issuerKeypair.publicKey());
const transaction = new StellarSdk.TransactionBuilder(...)
  .addOperation(
    StellarSdk.Operation.setTrustLineFlags({
      trustor: distributorKeypair.publicKey(),
      asset: astroDollar,
      flags: {
        authorized: true,
      },
    }),
  )
  .setTimeout(100)
  .build();
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from stellar_sdk import SorobanServer, Keypair, Network, TransactionBuilder, SetTrustLineFlags

server = SorobanServer("https://soroban-testnet.stellar.org")
issuer_account = server.load_account(issuer_keypair.public_key)

transaction = (
    TransactionBuilder(...)
    .append_set_trust_line_flags_op(
        trustor=distributor_keypair.public_key,
        asset=astro_dollar,
        flags=SetTrustLineFlags.AUTHORIZED_FLAG
    )
    .set_timeout(100)
    .build()
)
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
TransactionBuilderAccount issuerAccount = server.getAccount(issuerKeys.getAccountId());
Transaction transaction = new TransactionBuilder(...)
  .addOperation(SetTrustlineFlagsOperation.builder()
    .trustor(distributorKeys.getAccountId())
    .asset(astroDollar)
    .setFlags(EnumSet.of(TrustLineFlags.AUTHORIZED_FLAG))
    .clearFlags(EnumSet.noneOf(TrustLineFlags.class))
    .build())
  .setBaseFee(Transaction.MIN_BASE_FEE)
  .setTimeout(100)
  .build();
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
issuerAccount, _ := client.LoadAccount(ctx, issuerKeypair.Address())

transaction, _ := txnbuild.NewTransaction(
  txnbuild.TransactionParams{
    SourceAccount:        issuerAccount,
    IncrementSequenceNum: true,
    BaseFee:              txnbuild.MinBaseFee,
    Operations: []txnbuild.Operation{
      &txnbuild.SetTrustLineFlags{
        Trustor:   distributorKeypair.Address(),
        Asset:     astroDollar,
        Authorized: txnbuild.AuthorizeFlag,
      },
    },
    Timebounds: txnbuild.NewInfiniteTimeout(),
  },
)
```

## Full Code Sample

```js JavaScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
var StellarSdk = require("@stellar/stellar-sdk");
var server = new StellarSdk.rpc.Server("https://soroban-testnet.stellar.org");

// Keys for accounts to issue and receive the new asset
var issuerKeys = StellarSdk.Keypair.fromSecret(
  "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4",
);
var receivingKeys = StellarSdk.Keypair.fromSecret(
  "SDSAVCRE5JRAI7UFAVLE5IMIZRD6N6WOJUWKY4GFN34LOBEEUS4W2T2D",
);

// Create an object to represent the new asset
var astroDollar = new StellarSdk.Asset("AstroDollar", issuerKeys.publicKey());

// RPC accepts a transaction and answers `PENDING`, so we poll for the result
async function submit(transaction) {
  var sendResponse = await server.sendTransaction(transaction);
  if (sendResponse.status !== "PENDING") {
    throw new Error("Submission failed: " + sendResponse.status);
  }

  var finalResponse = await server.pollTransaction(sendResponse.hash);
  if (finalResponse.status !== "SUCCESS") {
    throw new Error("Transaction failed: " + finalResponse.status);
  }

  return finalResponse;
}

async function issueAstroDollar() {
  // First, the receiving account must trust the asset
  var receiver = await server.getAccount(receivingKeys.publicKey());
  var trustTransaction = new StellarSdk.TransactionBuilder(receiver, {
    fee: 100,
    networkPassphrase: StellarSdk.Networks.TESTNET,
  })
    // The `changeTrust` operation creates (or alters) a trustline
    // The `limit` parameter below is optional
    .addOperation(
      StellarSdk.Operation.changeTrust({
        asset: astroDollar,
        limit: "1000",
      }),
    )
    // setTimeout is required for a transaction
    .setTimeout(100)
    .build();
  trustTransaction.sign(receivingKeys);
  console.log(await submit(trustTransaction));

  // Second, the issuing account actually sends a payment using the asset
  var issuer = await server.getAccount(issuerKeys.publicKey());
  var paymentTransaction = new StellarSdk.TransactionBuilder(issuer, {
    fee: 100,
    networkPassphrase: StellarSdk.Networks.TESTNET,
  })
    .addOperation(
      StellarSdk.Operation.payment({
        destination: receivingKeys.publicKey(),
        asset: astroDollar,
        amount: "10",
      }),
    )
    // setTimeout is required for a transaction
    .setTimeout(100)
    .build();
  paymentTransaction.sign(issuerKeys);
  console.log(await submit(paymentTransaction));
}

issueAstroDollar().catch(function (error) {
  console.error("Error!", error);
});
```

```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
from stellar_sdk import Asset, Keypair, Network, SorobanServer, TransactionBuilder
from stellar_sdk.soroban_rpc import GetTransactionStatus, SendTransactionStatus

# Configure Stellar SDK to talk to the Stellar RPC instance hosted by SDF
# To use the live network, set the hostname to a mainnet RPC provider
server = SorobanServer("https://soroban-testnet.stellar.org")
# Use test network, if you need to use public network, please set it to `Network.PUBLIC_NETWORK_PASSPHRASE`
network_passphrase = Network.TESTNET_NETWORK_PASSPHRASE


# RPC accepts a transaction and answers PENDING, so we poll for the result
def submit(transaction):
    send_response = server.send_transaction(transaction)
    if send_response.status != SendTransactionStatus.PENDING:
        raise RuntimeError(f"Submission failed: {send_response.status}")

    final_response = server.poll_transaction(send_response.hash)
    if final_response.status != GetTransactionStatus.SUCCESS:
        raise RuntimeError(f"Transaction failed: {final_response.status}")

    return final_response


# Keys for accounts to issue and receive the new asset
issuerKeypair = Keypair.from_secret(
    "SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4"
)
issuer_public = issuerKeypair.public_key

distributor_keypair = Keypair.from_secret(
    "SDSAVCRE5JRAI7UFAVLE5IMIZRD6N6WOJUWKY4GFN34LOBEEUS4W2T2D"
)
distributor_public = distributor_keypair.public_key

# Transactions require a valid sequence number that is specific to this account.
# We can fetch the current sequence number for the source account from RPC.
distributor_account = server.load_account(distributor_public)

# Create an object to represent the new asset
astro_dollar = Asset("AstroDollar", issuer_public)

# First, the receiving account must trust the asset
trust_transaction = (
    TransactionBuilder(
        source_account=distributor_account,
        network_passphrase=network_passphrase,
        base_fee=100,
    )
    #  The `changeTrust` operation creates (or alters) a trustline
    #  The `limit` parameter below is optional
    .append_change_trust_op(asset=astro_dollar, limit="1000")
    .set_timeout(100)
    .build()
)

trust_transaction.sign(distributor_keypair)
trust_transaction_resp = submit(trust_transaction)
print(f"Change Trust Transaction Resp:\n{trust_transaction_resp}")

issuer_account = server.load_account(issuer_public)
# Second, the issuing account actually sends a payment using the asset.
payment_transaction = (
    TransactionBuilder(
        source_account=issuer_account,
        network_passphrase=network_passphrase,
        base_fee=100,
    )
    .append_payment_op(
        destination=distributor_public,
        asset=astro_dollar,
        amount="10",
    )
    .build()
)
payment_transaction.sign(issuerKeypair)
payment_transaction_resp = submit(payment_transaction)
print(f"Payment Transaction Resp:\n{payment_transaction_resp}")
```

```java Java theme={"theme":{"light":"github-light","dark":"github-dark"}}
SorobanServer server = new SorobanServer("https://soroban-testnet.stellar.org");

// Keys for accounts to issue and receive the new asset
KeyPair issuerKeys = KeyPair
  .fromSecretSeed("SCZANGBA5YHTNYVVV4C3U252E2B6P6F5T3U6MM63WBSBZATAQI3EBTQ4");
KeyPair receivingKeys = KeyPair
  .fromSecretSeed("SDSAVCRE5JRAI7UFAVLE5IMIZRD6N6WOJUWKY4GFN34LOBEEUS4W2T2D");

// Create an object to represent the new asset
Asset astroDollar = Asset.createNonNativeAsset("AstroDollar", issuerKeys.getAccountId());

// First, the receiving account must trust the asset
TransactionBuilderAccount receiving = server.getAccount(receivingKeys.getAccountId());
Transaction allowAstroDollars = new TransactionBuilder(receiving, Network.TESTNET)
  .addOperation(
    // The `ChangeTrust` operation creates (or alters) a trustline
    // The second parameter limits the amount the account can hold
    ChangeTrustOperation.builder().asset(new ChangeTrustAsset(astroDollar)).limit(new BigDecimal("1000")).build())
  .setBaseFee(Transaction.MIN_BASE_FEE)
  .setTimeout(180)
  .build();
allowAstroDollars.sign(receivingKeys);

// RPC accepts a transaction and answers PENDING, so we poll for the result
SendTransactionResponse trustSend = server.sendTransaction(allowAstroDollars);
if (trustSend.getStatus() != SendTransactionStatus.PENDING) {
  throw new RuntimeException("Submission failed: " + trustSend.getStatus());
}
GetTransactionResponse trustResult = server.pollTransaction(trustSend.getHash());
System.out.println("Change Trust Transaction: " + trustResult.getStatus());

// Second, the issuing account actually sends a payment using the asset
TransactionBuilderAccount issuer = server.getAccount(issuerKeys.getAccountId());
Transaction sendAstroDollars = new TransactionBuilder(issuer, Network.TESTNET)
  .addOperation(
    PaymentOperation.builder().destination(receivingKeys.getAccountId()).asset(astroDollar).amount(new BigDecimal("10")).build())
  .setBaseFee(Transaction.MIN_BASE_FEE)
  .setTimeout(180)
  .build();
sendAstroDollars.sign(issuerKeys);

SendTransactionResponse paymentSend = server.sendTransaction(sendAstroDollars);
if (paymentSend.getStatus() != SendTransactionStatus.PENDING) {
  throw new RuntimeException("Submission failed: " + paymentSend.getStatus());
}
GetTransactionResponse paymentResult = server.pollTransaction(paymentSend.getHash());
System.out.println("Payment Transaction: " + paymentResult.getStatus());
```

```go Go theme={"theme":{"light":"github-light","dark":"github-dark"}}
package main

import (
  "context"
  "log"

  "github.com/stellar/go-stellar-sdk/clients/rpcclient"
  "github.com/stellar/go-stellar-sdk/keypair"
  "github.com/stellar/go-stellar-sdk/network"
  "github.com/stellar/go-stellar-sdk/txnbuild"

  protocol "github.com/stellar/go-stellar-sdk/protocols/rpc"
)

// RPC accepts a transaction and answers PENDING, so we poll for the result
func submit(ctx context.Context, client *rpcclient.Client, tx *txnbuild.Transaction) protocol.GetTransactionResponse {
  txnB64, err := tx.Base64()
  if err != nil {
    log.Fatal(err)
  }

  sendResp, err := client.SendTransaction(ctx, protocol.SendTransactionRequest{Transaction: txnB64})
  if err != nil {
    log.Fatal(err)
  }
  if sendResp.Status != "PENDING" {
    log.Fatalf("Submission failed: %s", sendResp.Status)
  }

  finalResp, err := client.PollTransaction(ctx, sendResp.Hash)
  if err != nil {
    log.Fatal(err)
  }
  if finalResp.Status != protocol.TransactionStatusSuccess {
    log.Fatalf("Transaction failed: %s", finalResp.Status)
  }

  return finalResp
}

func main() {
  ctx := context.Background()
  client := rpcclient.NewClient("https://soroban-testnet.stellar.org", nil)
  defer client.Close()

  // Remember, these are just examples, so replace them with your own seeds.
  issuerSeed := "SDR4C2CKNCVK4DWMTNI2IXFJ6BE3A6J3WVNCGR6Q3SCMJDTSVHMJGC6U"
  distributorSeed := "SBUW3DVYLKLY5ZUJD5PL2ZHOFWJSVWGJA47F6FLO66UUFZLUUA2JVU5U"

  /*
   * We omit error checks here for brevity, but you should always check your
   * return values.
   */

  // Keys for accounts to issue and distribute the new asset.
  issuer, err := keypair.ParseFull(issuerSeed)
  distributor, err := keypair.ParseFull(distributorSeed)

  issuerAccount, err := client.LoadAccount(ctx, issuer.Address())
  distributorAccount, err := client.LoadAccount(ctx, distributor.Address())

  // Create an object to represent the new asset
  astroDollar := txnbuild.CreditAsset{Code: "AstroDollar", Issuer: issuer.Address()}

  // First, the receiving (distribution) account must trust the asset from the
  // issuer.
  tx, err := txnbuild.NewTransaction(
    txnbuild.TransactionParams{
      SourceAccount:        distributorAccount,
      IncrementSequenceNum: true,
      BaseFee:              txnbuild.MinBaseFee,
      Preconditions: txnbuild.Preconditions{
				TimeBounds: txnbuild.NewInfiniteTimeout(),
			},
      Operations: []txnbuild.Operation{
        &txnbuild.ChangeTrust{
          Line:  astroDollar.MustToChangeTrustAsset(),
          Limit: "5000",
        },
      },
    },
  )

  signedTx, err := tx.Sign(network.TestNetworkPassphrase, distributor)
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("Trust: %s\n", submit(ctx, client, signedTx).TransactionHash)

  // Second, the issuing account actually sends a payment using the asset
  tx, err = txnbuild.NewTransaction(
    txnbuild.TransactionParams{
      SourceAccount:        issuerAccount,
      IncrementSequenceNum: true,
      BaseFee:              txnbuild.MinBaseFee,
      Preconditions: txnbuild.Preconditions{
				TimeBounds: txnbuild.NewInfiniteTimeout(),
			},
      Operations: []txnbuild.Operation{
        &txnbuild.Payment{
          Destination: distributor.Address(),
          Asset:       astroDollar,
          Amount:      "10",
        },
      },
    },
  )

  signedTx, err = tx.Sign(network.TestNetworkPassphrase, issuer)
  if err != nil {
    log.Fatal(err)
  }
  log.Printf("Pay: %s\n", submit(ctx, client, signedTx).TransactionHash)
}
```
