// address to hold the minted tokens. You can use which you want.
let addresses = [(await wallet.getAddresses())[0]];
// blockchain config, this is where you can find protocol params, slotsPerKESPeriod etc.
// This lib comes with Mainnet, Testnet and LocalCluster config (Config.Mainnet, Config.Testnet and Config.LocalCluster), but you may consider provide your own to make sure they are up to date.
// You can find the latest config files here: https://hydra.iohk.io/build/6498473/download/1/index.html
let config = { ..., "protocolParams": {... "minFeeA": 44, ..., "minFeeB": 155381, ...} }
// policy public/private keypair
let keyPair= Seed.generateKeyPair();
let policyVKey = keyPair.publicKey;
let policySKey = keyPair.privateKey;
// generate single issuer native script
let keyHash = Seed.getKeyHash(policyVKey);
let script = Seed.buildSingleIssuerScript(keyHash);
let scriptHash = Seed.getScriptHash(script);
let policyId = Seed.getPolicyId(scriptHash);
description: "Tango crypto coin",
let asset = new AssetWallet(policyId, "Tango", 1000000);
let tokens = [new TokenWallet(asset, script, [keyPair])];
let scripts = tokens.map(t => t.script);
// get min ada for address holding tokens
let minAda = Seed.getMinUtxoValueWithAssets([asset], config);
let info = await walletServer.getNetworkInformation();
let ttl = info.node_tip.absolute_slot_number * 12000;
// get coin selection structure (without the assets)
let coinSelection = await wallet.getCoinSelection(addresses, amounts, data);
let rootKey = Seed.deriveRootKey(payeer.mnemonic_sentence);
let signingKeys = coinSelection.inputs.map(i => {
let privateKey = Seed.deriveKey(rootKey, i.derivation_path).to_raw_key();
// add policy signing keys
tokens.filter(t => t.scriptKeyPairs).forEach(t => signingKeys.push(...t.scriptKeyPairs.map(k => k.privateKey.to_raw_key())));
let metadata = Seed.buildTransactionMetadata(data);
// the wallet currently doesn't support including tokens not previuosly minted
// so we need to include it manually.
coinSelection.outputs = coinSelection.outputs.map(output => {
if (output.address === addresses[0].address) {
output.assets = tokens.map(t => {
let asset: WalletsAssetsAvailable = {
policy_id: t.asset.policy_id,
asset_name: Buffer.from(t.asset.asset_name).toString('hex'),
quantity: t.asset.quantity
// we need to sing the tx and calculate the actual fee and the build again
// since the coin selection doesnt calculate the fee with the asset tokens included
let txBody = Seed.buildTransactionWithToken(coinSelection, ttl, tokens, signingKeys, {data: data, config: config});
let tx = Seed.sign(txBody, signingKeys, metadata, scripts);
let signed = Buffer.from(tx.to_bytes()).toString('hex');
let txId = await walletServer.submitTx(signed);