We've updated our Terms of Service. By continuing to use our services, you agree to the updated Terms.

Kadena

Kadena

#Overview

Kadena is a secure and scalable proof-of-work network designed to power global financial systems. It is unique in its braided multi-chain architecture, currently consisting of 20 different chains per network.

Magic interacts with the Kadena blockchain via Magic's extension NPM package @magic-ext/kadena. The Kadena extension also lets you interact with the blockchain using methods from Kadena's Javascript SDK.

note

You can skip straight to our kitchen sink example directly:

👉 Kadena Example

NPM
Yarn
01npm install --save @magic-ext/kadena

#Initialization

Developers can initialize the Kadena extension by providing the following config

  • rpcUrl - endpoint for the Kadena node
  • chainId - chain ID for the Kadena network (0 - 19)
  • networkId - network ID for the Kadena network
  • createAccountsOnChain - this field specifies whether or not Magic will submit a create-account transaction as part of the new user sign up flow. Note that due to the on-chain transaction, enabling this will result in signups that take up to 30 seconds.
Testnet
Mainnet
01import { Magic } from 'magic-sdk';
02import { KadenaExtension } from '@magic-ext/kadena';
03
04export const chainId = '0';
05export const networkId = 'testnet04';
06export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`;
07
08
09const magic = new Magic('YOUR_API_KEY', {
10  extensions: [
11    new KadenaExtension({
12      rpcUrl,
13      chainId,
14      networkId,
15      createAccountsOnChain: true,
16    }),
17  ],
18});

#Common Methods

#SpireKey Login

Magic supports Kadena's SpireKey library, allowing users to login with just a passkey. Visit the Kadena docs to learn more about SpireKey.

Typescript
01const account = magic.kadena.loginWithSpireKey();

#Get User Info

Returns information about the authenticated user, such as accountName, publicKey, loginType (‘email_otp’, ‘sms’, ‘spirekey’, etc), isMfaEnabled, email, phoneNumber, and spireKeyInfo.

Typescript
01const userInfo = magic.kadena.getUserInfo();

#Get Test KDA Tokens

Before you can send a transaction on the Kadena blockchain, you'll need to acquire some test KDA.

  1. Go to our Kadena Example application

  2. Login with your email address

  3. Copy your Kadena account

  4. Go to the Kadena Faucet

  5. Paste your copied Kadena public address in the text input

  6. Now you can use your test KDA in our example app

#Sign Transaction (with SpireKey user)

To sign a Kadena transaction for a SpireKey user, you can call the magic.kadena.signTransactionWithSpireKey() method.

Typescript
01import { addSignatures, createClient, Pact } from "@kadena/client";
02import { PactNumber } from "@kadena/pactjs";
03
04export const chainId = "0";
05export const networkId = "testnet04";
06export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`;
07
08const handleSendTransaction = async () => {
09  const userInfo = await magic.kadena.getInfo();
10  const kadenaClient = createClient(rpcUrl);
11
12  const fromAccount = userInfo.accountName;
13  const senderPublicKey = userInfo.publicKey;
14
15  const toAccount = "k:...";
16  const receiverPublicKey = toAccount.substring(2);
17
18  const amount = new PactNumber(sendAmount).toPactDecimal();
19
20  const transaction = Pact.builder
21    .execution(
22      (Pact.modules as any).coin.transfer(fromAccount, toAccount, amount)
23    )
24    .addSigner(
25      {
26        pubKey: senderPublicKey,
27        scheme: "WebAuthn",
28      },
29      (withCapability: any) => [
30        withCapability("coin.GAS"),
31        withCapability("coin.TRANSFER", fromAccount, toAccount, amount),
32      ]
33    )
34    .addData("receiverKeyset", {
35      keys: [receiverPubKey],
36      pred: "keys-all",
37    })
38    .setMeta({ chainId, senderAccount: fromAccount })
39    .setNetworkId(networkId)
40    .createTransaction();
41
42  try {
43    const { transactions } = await magic.kadena.signTransactionWithSpireKey(
44      transaction
45    );
46    const signedTx = transactions[0];
47    const transactionDescriptor = await kadenaClient.submit(signedTx);
48    const response = await kadenaClient.listen(transactionDescriptor);
49    if (response.result.status === "failure") {
50      console.error(response.result.error);
51    } else {
52      console.log(response.result);
53    }
54  } catch (error) {
55    console.error("Failed to send transaction", error);
56  }
57};

#Sign Transaction (with non-SpireKey user)

To sign a standard Kadena transaction, you can call the magic.kadena.signTransaction() method.

Typescript
01import { addSignatures, createClient, Pact } from "@kadena/client";
02import { PactNumber } from "@kadena/pactjs";
03
04export const chainId = "0";
05export const networkId = "testnet04";
06export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`;
07
08const handleSendTransaction = async () => {
09  const userInfo = await magic.kadena.getInfo();
10  const kadenaClient = createClient(rpcUrl);
11
12  const fromAccount = userInfo.accountName;
13  const senderPublicKey = userInfo.publicKey;
14
15  const toAccount = "k:...";
16  const receiverPublicKey = toAccount.substring(2);
17
18  const amount = new PactNumber(sendAmount).toPactDecimal();
19
20  const transaction = Pact.builder
21    .execution(
22      (Pact.modules as any).coin.transfer(fromAccount, toAccount, amount)
23    )
24    .addSigner(senderPubKey, (withCapability: any) => [
25      withCapability("coin.GAS"),
26      withCapability("coin.TRANSFER", fromAccount, toAccount, amount),
27    ])
28    .addData("receiverKeyset", {
29      keys: [receiverPubKey],
30      pred: "keys-all",
31    })
32    .setMeta({ chainId, senderAccount: fromAccount })
33    .setNetworkId(networkId)
34    .createTransaction();
35
36  try {
37    const signature = await magic.kadena.signTransaction(transaction.hash);
38    const signedTx = addSignatures(transaction, signature);
39    const transactionDescriptor = await kadenaClient.submit(signedTx);
40    const response = await kadenaClient.listen(transactionDescriptor);
41    if (response.result.status === "failure") {
42      console.error(response.result.error);
43    } else {
44      console.log(response.result);
45    }
46  } catch (error) {
47    console.error("Failed to send transaction", error);
48  }
49};

#Resources