Documentation Index
Fetch the complete documentation index at: https://docs.magic.link/llms.txt
Use this file to discover all available pages before exploring further.
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.
You can skip straight to our kitchen sink example directly: Kadena
Example
Installation
npm 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.
import { Magic } from "magic-sdk";
import { KadenaExtension } from "@magic-ext/kadena";
export const chainId = "0";
export const networkId = "testnet04";
export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`;
const magic = new Magic('YOUR_API_KEY', {
extensions: [
new KadenaExtension({
rpcUrl,
chainId,
networkId,
createAccountsOnChain: true,
}),
],
});
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.
const 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.
const 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.
- Go to our Kadena Example application
- Login with your email address
- Copy your Kadena account
- Go to the Kadena Faucet
- Paste your copied Kadena public address in the text input
- 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.
import { addSignatures, createClient, Pact } from "@kadena/client";
import { PactNumber } from "@kadena/pactjs";
export const chainId = "0";
export const networkId = "testnet04";
export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`;
const handleSendTransaction = async () => {
const userInfo = await magic.kadena.getInfo();
const kadenaClient = createClient(rpcUrl);
const fromAccount = userInfo.accountName;
const senderPublicKey = userInfo.publicKey;
const toAccount = "k:...";
const receiverPublicKey = toAccount.substring(2);
const amount = new PactNumber(sendAmount).toPactDecimal();
const transaction = Pact.builder
.execution(
(Pact.modules as any).coin.transfer(fromAccount, toAccount, amount)
)
.addSigner(
{
pubKey: senderPublicKey,
scheme: "WebAuthn",
},
(withCapability: any) => [
withCapability("coin.GAS"),
withCapability("coin.TRANSFER", fromAccount, toAccount, amount),
]
)
.addData("receiverKeyset", {
keys: [receiverPubKey],
pred: "keys-all",
})
.setMeta({ chainId, senderAccount: fromAccount })
.setNetworkId(networkId)
.createTransaction();
try {
const { transactions } = await magic.kadena.signTransactionWithSpireKey(
transaction
);
const signedTx = transactions[0];
const transactionDescriptor = await kadenaClient.submit(signedTx);
const response = await kadenaClient.listen(transactionDescriptor);
if (response.result.status === "failure") {
console.error(response.result.error);
} else {
console.log(response.result);
}
} catch (error) {
console.error("Failed to send transaction", error);
}
};
Sign Transaction (with non-SpireKey user)
To sign a standard Kadena transaction, you can call the magic.kadena.signTransaction() method.
import { addSignatures, createClient, Pact } from "@kadena/client";
import { PactNumber } from "@kadena/pactjs";
export const chainId = "0";
export const networkId = "testnet04";
export const rpcUrl = `https://api.testnet.chainweb.com/chainweb/0.0/${networkId}/chain/${chainId}/pact`;
const handleSendTransaction = async () => {
const userInfo = await magic.kadena.getInfo();
const kadenaClient = createClient(rpcUrl);
const fromAccount = userInfo.accountName;
const senderPublicKey = userInfo.publicKey;
const toAccount = "k:...";
const receiverPublicKey = toAccount.substring(2);
const amount = new PactNumber(sendAmount).toPactDecimal();
const transaction = Pact.builder
.execution(
(Pact.modules as any).coin.transfer(fromAccount, toAccount, amount)
)
.addSigner(senderPubKey, (withCapability: any) => [
withCapability("coin.GAS"),
withCapability("coin.TRANSFER", fromAccount, toAccount, amount),
])
.addData("receiverKeyset", {
keys: [receiverPubKey],
pred: "keys-all",
})
.setMeta({ chainId, senderAccount: fromAccount })
.setNetworkId(networkId)
.createTransaction();
try {
const signature = await magic.kadena.signTransaction(transaction.hash);
const signedTx = addSignatures(transaction, signature);
const transactionDescriptor = await kadenaClient.submit(signedTx);
const response = await kadenaClient.listen(transactionDescriptor);
if (response.result.status === "failure") {
console.error(response.result.error);
} else {
console.log(response.result);
}
} catch (error) {
console.error("Failed to send transaction", error);
}
};
Resources