Deno & Fetch

Using Deno (or Node) & fetch to build, sign* and submit a transaction

Introduction

There are two ways to create a transaction, the first one is by passing the Cardano wallet address for the utxos (only available on testnet networks), and the second one (required for production) usually used with a frontend (wallet extension), requires to get a list of all cbor utxos to be used for the transaction.

Objectives

This example sends 10ADA from one wallet to another.

The wallets are on Preprod network and using a CIP-30 compatible wallet (So the signature is done in the browser)

Requirements

  • A Cardano wallet with ADA

  • A wallet to send ADA to

  • A wallet extension to sign the transaction

  • An API key

API Request Structure

Payload Format (Using an address as utxos)

Important: This demo is meant for educational and testing purposes only. In production, please pass the UTXO list for your wallet. We recommend using the @ada-anvil/weld wallet connector to easily retrieve UTXOs from connected wallets. In this example, the API will fetch the UTXO list for you and automatically determine the UTXO(s) to be used for the transaction.

{
  "changeAddress": "addr_sender...",
  "outputs": [
    {
      "address": "addr_recipient...",
      "lovelace": 10_000_000
    }
  ]
}

Implementation

Configuration and Parameters (using Deno and Fetch)

Using a preprod wallet all value needed for a transaction

const SENDER_ADDRESS = "addr_test1qrydyk6uw6cehk5u3zspyz3dhnwzmhfls2fp42vv5dv9g2z3885pg4kpkn30ptezc855lu3w5ey93zcr5lrezjmwkftqg8xvge";
const RECEIVER_ADDRESS = "addr_test1qr0tkwvlln0v5fljdxceudmlpt5y6szc84vpj4skm836tgn4hsqaesgg97l8ppy5rsn0alj8pth6lqe20fdyydsdgw6sr74cyt";
// 10 ADA => 1ADA = 1'000'000LOVELACE
const LOVELACE_AMOUNT = 10_000_000;
// See Authentication page for API key details.
const X_API_KEY = "testnet_EyrkvCWDZqjkfLSe1pxaF0hXxUcByHEhHuXIBjt9";

Request Body

Body Structure for creating a basic transaction using the previously collected values.

const BODY = {
  changeAddress: SENDER_ADDRESS,
  outputs: [
    {
      address: RECEIVER_ADDRESS,
      lovelace: LOVELACE_AMOUNT,
    },
  ],
};

API Call (using Deno and Fetch)

Basic POST call with Fetch

basic-transaction.ts
const response = await fetch(
    `https://preprod.api.ada-anvil.app/v2/services/transactions/build`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
        "x-api-key": X_API_KEY,
      },
      body: JSON.stringify(BODY),
    }
  );

  console.log(await response.json());

Deno Command

deno run --allow-net basic-transaction.ts

Output

{
  "hash": "b1f159d88e9dece4d327352c03a6fbb9484533dee60207367a2689f632650c9c",
  "complete": "84a400d9010281825820c83c3a8285c7b08c2cec3abf0c91dcec5afee531d6a0eeef002dd6d75456927d01018282583900debb399ffcdeca27f269b19e377f0ae84d40583d58195616d9e3a5a275bc01dcc1082fbe7084941c26fefe470aefaf832a7a5a42360d43b51a0098968082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a43c6a5fc021a0003cb05031a04ebdd50a0f5f6",
  "stripped": "84a400d9010281825820c83c3a8285c7b08c2cec3abf0c91dcec5afee531d6a0eeef002dd6d75456927d01018282583900debb399ffcdeca27f269b19e377f0ae84d40583d58195616d9e3a5a275bc01dcc1082fbe7084941c26fefe470aefaf832a7a5a42360d43b51a0098968082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a43c6a5fc021a0003cb05031a04ebdd50a0f5f6",
  "witnessSet": "a0"
}

The Whole File (Deno Version)

basic-transaction.ts
const SENDER_ADDRESS =
  "addr_test1qrydyk6uw6cehk5u3zspyz3dhnwzmhfls2fp42vv5dv9g2z3885pg4kpkn30ptezc855lu3w5ey93zcr5lrezjmwkftqg8xvge";
const RECEIVER_ADDRESS =
  "addr_test1qr0tkwvlln0v5fljdxceudmlpt5y6szc84vpj4skm836tgn4hsqaesgg97l8ppy5rsn0alj8pth6lqe20fdyydsdgw6sr74cyt";

// 10 ADA => 1ADA = 1'000'000LOVELACE
const LOVELACE_AMOUNT = 10_000_000;

// See Authentication page for API key details.
const X_API_KEY = "testnet_EyrkvCWDZqjkfLSe1pxaF0hXxUcByHEhHuXIBjt9";
const API_URL = "https://preprod.api.ada-anvil.app/v2/services";
const HEADERS = { "Content-Type": "application/json", "x-api-key": X_API_KEY };

const BODY = {
  changeAddress: SENDER_ADDRESS,
  outputs: [
    {
      address: RECEIVER_ADDRESS,
      lovelace: LOVELACE_AMOUNT,
    },
  ],
};

const response = await fetch(`${API_URL}/transactions/build`, {
  method: "POST",
  headers: HEADERS,
  body: JSON.stringify(BODY),
});

console.log(await response.json());

export {};

Using Fetched Utxos

Payload (Using a list of utxos)

You can use this payload when you can fetch the utxos, for example, when you have a wallet extension

{
  "utxos": ["8282...", "8282...", "..."],
  "changeAddress": "addr_sender...",
  "outputs": [
    {
      "address": "addr_recipient...",
      "lovelace": 10_000_000
    }
  ]
}

Add the required UTXOs for your transaction. (usually all of them)

Get UTXO

You can retrieve your UTXOs from your wallet using these functions in the browser console. (Example: Chrome console with Eternl)

const wallet = await window.cardano.eternl.enabled();
const utxos = await wallet.getUtxos();
console.log(utxos);

Then, copy your UTXO array and include it as a parameter in the request body, as shown below.

Params

const UTXOS = [
  "828258200599b9572ee291d70e2ffe6ac876c1e814c952a1633e4c48ac58e39726123d9d0082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a002dc6c0",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0282583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a3b9a6a05",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0382583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a3b9a6a05",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0482583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dcd3507",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0582583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dcd3502",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0682583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dcd3502",
  "828258209856940b54a9048607a5b081e8718602571e57f59de745c562ce7b74776c89a90082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb256821a0011f436a1581c1af660e4c58514a2f0ea167deca340381e55bed4aea60bc09c211417a14d416e76696c546573743133353601",
  "82825820a2cf6441b06a025f92d32d3e5faa17227d8f1d2310c0a1081ceaaa72d2dd6aa90182583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dca3e37",
  "82825820e1cd7eee71dcf9de2ea133f6932552d922ff6cc0a34908cdec8c0eae8c9664d80582583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a000f4240",
  "82825820c83c3a8285c7b08c2cec3abf0c91dcec5afee531d6a0eeef002dd6d75456927d0182583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a44630781",
  "828258203aeb86b1388189192281b6b2c114235cec91b4a1fc3aeb4d73b1721855b93f3c0082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561b00000002540be400",
];
const SENDER_ADDRESS = "addr_test1qrydyk6uw6cehk5u3zspyz3dhnwzmhfls2fp42vv5dv9g2z3885pg4kpkn30ptezc855lu3w5ey93zcr5lrezjmwkftqg8xvge";
const RECEIVER_ADDRESS = "addr_test1qr0tkwvlln0v5fljdxceudmlpt5y6szc84vpj4skm836tgn4hsqaesgg97l8ppy5rsn0alj8pth6lqe20fdyydsdgw6sr74cyt";
// 10 ADA => 1ADA = 1'000'000LOVELACE
const LOVELACE_AMOUNT = 10_000_000;
// See Authentication page for API key details.
const X_API_KEY = "testnet_EyrkvCWDZqjkfLSe1pxaF0hXxUcByHEhHuXIBjt9";

API POST Request Body

Body Structure for creating a basic transaction using the previously collected values.

const BODY = {
  utxos: UTXOS,
  changeAddress: SENDER_ADDRESS,
  outputs: [
    {
      address: RECEIVER_ADDRESS,
      lovelace: LOVELACE_AMOUNT,
    },
  ],
};

Fetch Command with Deno

Basic POST call with Fetch

const response = await fetch(
  `${API_URL}/transactions/build`,
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": X_API_KEY,
    },
    body: JSON.stringify(BODY),
  }
);

console.log(await response.json());

Deno Command

deno run --allow-net basic-transaction.ts

Output

{
  hash: "b1f159d88e9dece4d327352c03a6fbb9484533dee60207367a2689f632650c9c",
  complete: "84a400d9010281825820c83c3a8285c7b08c2cec3abf0c91dcec5afee531d6a0eeef002dd6d75456927d01018282583900debb399ffcdeca27f269b19e377f0ae84d40583d58195616d9e3a5a275bc01dcc1082fbe7084941c26fefe470aefaf832a7a5a42360d43b51a0098968082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a43c6a5fc021a0003cb05031a04ebdd50a0f5f6",
  stripped: "84a400d9010281825820c83c3a8285c7b08c2cec3abf0c91dcec5afee531d6a0eeef002dd6d75456927d01018282583900debb399ffcdeca27f269b19e377f0ae84d40583d58195616d9e3a5a275bc01dcc1082fbe7084941c26fefe470aefaf832a7a5a42360d43b51a0098968082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a43c6a5fc021a0003cb05031a04ebdd50a0f5f6",
  witnessSet: "a0"
}

Sign and Submit the Transaction

The transaction can be sign and submitted.

Sign TransactionSubmit Transaction

The Whole File (Deno Version)

basic-transaction.ts
const UTXOS = [
  "828258200599b9572ee291d70e2ffe6ac876c1e814c952a1633e4c48ac58e39726123d9d0082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a002dc6c0",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0282583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a3b9a6a05",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0382583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a3b9a6a05",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0482583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dcd3507",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0582583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dcd3502",
  "8282582020932c96eccc8ffdde138945a492a568942f7ef9181b1805eaae9a4bfdede28a0682583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dcd3502",
  "828258209856940b54a9048607a5b081e8718602571e57f59de745c562ce7b74776c89a90082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb256821a0011f436a1581c1af660e4c58514a2f0ea167deca340381e55bed4aea60bc09c211417a14d416e76696c546573743133353601",
  "82825820a2cf6441b06a025f92d32d3e5faa17227d8f1d2310c0a1081ceaaa72d2dd6aa90182583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a1dca3e37",
  "82825820e1cd7eee71dcf9de2ea133f6932552d922ff6cc0a34908cdec8c0eae8c9664d80582583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a000f4240",
  "82825820c83c3a8285c7b08c2cec3abf0c91dcec5afee531d6a0eeef002dd6d75456927d0182583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561a44630781",
  "828258203aeb86b1388189192281b6b2c114235cec91b4a1fc3aeb4d73b1721855b93f3c0082583900c8d25b5c76b19bda9c88a0120a2dbcdc2ddd3f82921aa98ca35854285139e81456c1b4e2f0af22c1e94ff22ea648588b03a7c7914b6eb2561b00000002540be400",
];
const SENDER_ADDRESS = "addr_test1qrydyk6uw6cehk5u3zspyz3dhnwzmhfls2fp42vv5dv9g2z3885pg4kpkn30ptezc855lu3w5ey93zcr5lrezjmwkftqg8xvge";
const RECEIVER_ADDRESS = "addr_test1qr0tkwvlln0v5fljdxceudmlpt5y6szc84vpj4skm836tgn4hsqaesgg97l8ppy5rsn0alj8pth6lqe20fdyydsdgw6sr74cyt";
// 10 ADA => 1ADA = 1'000'000LOVELACE
const LOVELACE_AMOUNT = 10_000_000;
// See Authentication page for API key details.
const X_API_KEY = "testnet_EyrkvCWDZqjkfLSe1pxaF0hXxUcByHEhHuXIBjt9";
const API_URL = "https://preprod.api.ada-anvil.app/v2/services";

const BODY = {
  utxos: UTXOS,
  changeAddress: SENDER_ADDRESS,
  outputs: [
    {
      address: RECEIVER_ADDRESS,
      lovelace: LOVELACE_AMOUNT,
    },
  ],
};

const response = await fetch(
  `${API_URL}/transactions/build`,
  {
    method: "POST",
    headers: { "Content-Type": "application/json", "x-api-key": X_API_KEY },
    body: JSON.stringify(BODY),
  }
);

console.log(await response.json());

export {};

Last updated

Was this helpful?