From 1b4e3270c089a99ff98a7d1babc0f621912f7f7b Mon Sep 17 00:00:00 2001 From: Patriciu Nista Date: Wed, 2 Nov 2022 11:55:00 +0100 Subject: [PATCH] remove duplicated functions and fix typos --- .../example-cardano/index.js | 746 ++++++++++-------- 1 file changed, 400 insertions(+), 346 deletions(-) diff --git a/packages/yoroi-ergo-connector/example-cardano/index.js b/packages/yoroi-ergo-connector/example-cardano/index.js index af530b7e76..727ce70a52 100644 --- a/packages/yoroi-ergo-connector/example-cardano/index.js +++ b/packages/yoroi-ergo-connector/example-cardano/index.js @@ -1,38 +1,38 @@ -import * as CardanoWasm from '@emurgo/cardano-serialization-lib-browser'; -import { textPartFromWalletChecksumImagePart } from '@emurgo/cip4-js'; -import { createIcon } from '@download/blockies'; -import { getTtl } from './utils'; -import { Bech32Prefix } from '../../yoroi-extension/app/config/stringConfig'; -import { bytesToHex, hexToBytes } from './coreUtils'; - -const cardanoAccessBtnRow = document.querySelector('#request-button-row'); -const cardanoAuthCheck = document.querySelector('#check-identification'); -const cardanoAccessBtn = document.querySelector('#request-access'); -const connectionStatus = document.querySelector('#connection-status'); -const walletPlateSpan = document.querySelector('#wallet-plate'); -const walletIconSpan = document.querySelector('#wallet-icon'); -const getUnUsedAddresses = document.querySelector('#get-unused-addresses'); -const getUsedAddresses = document.querySelector('#get-used-addresses'); -const getChangeAddress = document.querySelector('#get-change-address'); -const getRewardAddresses = document.querySelector('#get-reward-addresses'); -const getAccountBalance = document.querySelector('#get-balance'); -const isEnabledBtn = document.querySelector('#is-enabled'); -const getUtxos = document.querySelector('#get-utxos'); -const submitTx = document.querySelector('#submit-tx'); -const signTx = document.querySelector('#sign-tx'); -const showUtxos = document.querySelector('#show-utxos'); -const createTx = document.querySelector('#create-tx'); -const getCollateralUtxos = document.querySelector('#get-collateral-utxos'); -const signData = document.querySelector('#sign-data'); -const alertEl = document.querySelector('#alert'); -const spinner = document.querySelector('#spinner'); -const utxosContainer = document.querySelector('#utxos'); -const getNFTs = document.getElementById('nfts'); -const getNetworkId = document.getElementById('get-network-id'); +import * as CardanoWasm from "@emurgo/cardano-serialization-lib-browser"; +import { textPartFromWalletChecksumImagePart } from "@emurgo/cip4-js"; +import { createIcon } from "@download/blockies"; +import { getTtl } from "./utils"; +import { Bech32Prefix } from "../../yoroi-extension/app/config/stringConfig"; +import { bytesToHex, hexToBytes } from "./coreUtils"; + +const cardanoAccessBtnRow = document.querySelector("#request-button-row"); +const cardanoAuthCheck = document.querySelector("#check-identification"); +const cardanoAccessBtn = document.querySelector("#request-access"); +const connectionStatus = document.querySelector("#connection-status"); +const walletPlateSpan = document.querySelector("#wallet-plate"); +const walletIconSpan = document.querySelector("#wallet-icon"); +const getUnUsedAddresses = document.querySelector("#get-unused-addresses"); +const getUsedAddresses = document.querySelector("#get-used-addresses"); +const getChangeAddress = document.querySelector("#get-change-address"); +const getRewardAddresses = document.querySelector("#get-reward-addresses"); +const getAccountBalance = document.querySelector("#get-balance"); +const isEnabledBtn = document.querySelector("#is-enabled"); +const getUtxos = document.querySelector("#get-utxos"); +const submitTx = document.querySelector("#submit-tx"); +const signTx = document.querySelector("#sign-tx"); +const showUtxos = document.querySelector("#show-utxos"); +const createTx = document.querySelector("#create-tx"); +const getCollateralUtxos = document.querySelector("#get-collateral-utxos"); +const signData = document.querySelector("#sign-data"); +const alertEl = document.querySelector("#alert"); +const spinner = document.querySelector("#spinner"); +const utxosContainer = document.querySelector("#utxos"); +const getNFTs = document.getElementById("nfts"); +const getNetworkId = document.getElementById("get-network-id"); let accessGranted = false; let cardanoApi; -let returnType = 'cbor'; +let returnType = "cbor"; let utxos; let selectedUtxoIdx = 0; let usedAddresses; @@ -42,16 +42,16 @@ let unsignedTransactionHex; let transactionHex; function isCBOR() { - return returnType === 'cbor'; + return returnType === "cbor"; } const mkcolor = (primary, secondary, spots) => ({ primary, secondary, spots }); const COLORS = [ - mkcolor('#E1F2FF', '#17D1AA', '#A80B32'), - mkcolor('#E1F2FF', '#FA5380', '#0833B2'), - mkcolor('#E1F2FF', '#F06EF5', '#0804F7'), - mkcolor('#E1F2FF', '#EBB687', '#852D62'), - mkcolor('#E1F2FF', '#F59F9A', '#085F48'), + mkcolor("#E1F2FF", "#17D1AA", "#A80B32"), + mkcolor("#E1F2FF", "#FA5380", "#0833B2"), + mkcolor("#E1F2FF", "#F06EF5", "#0804F7"), + mkcolor("#E1F2FF", "#EBB687", "#852D62"), + mkcolor("#E1F2FF", "#F59F9A", "#085F48"), ]; function createBlockiesIcon(seed) { @@ -67,11 +67,11 @@ function createBlockiesIcon(seed) { }); } -toggleSpinner('show'); +toggleSpinner("show"); function onApiConnectied(api) { - toggleSpinner('hide'); - let walletDisplay = 'an anonymous Yoroi Wallet'; + toggleSpinner("hide"); + let walletDisplay = "an anonymous Yoroi Wallet"; api.experimental.setReturnType(returnType); @@ -81,7 +81,10 @@ function onApiConnectied(api) { if (authEnabled) { const walletId = auth.getWalletId(); const pubkey = auth.getWalletPubkey(); - console.log('Auth acquired successfully: ', JSON.stringify({ walletId, pubkey })); + console.log( + "Auth acquired successfully: ", + JSON.stringify({ walletId, pubkey }) + ); const walletPlate = textPartFromWalletChecksumImagePart(walletId); walletDisplay = `Yoroi Wallet ${walletPlate}`; walletIconSpan.appendChild(createBlockiesIcon(walletId)); @@ -89,26 +92,26 @@ function onApiConnectied(api) { alertSuccess(`You have access to ${walletDisplay} now`); walletPlateSpan.innerHTML = walletDisplay; - toggleConnectionUI('status'); + toggleConnectionUI("status"); accessGranted = true; window.cardanoApi = cardanoApi = api; api.experimental.onDisconnect(() => { - alertWarrning(`Disconnected from ${walletDisplay}`); - toggleConnectionUI('button'); - walletPlateSpan.innerHTML = ''; - walletIconSpan.innerHTML = ''; + alertWarning(`Disconnected from ${walletDisplay}`); + toggleConnectionUI("button"); + walletPlateSpan.innerHTML = ""; + walletIconSpan.innerHTML = ""; }); if (authEnabled) { - console.log('Testing auth signatures'); + console.log("Testing auth signatures"); const messageJson = JSON.stringify({ - type: 'this is a random test message object', + type: "this is a random test message object", rndValue: Math.random(), }); const messageHex = bytesToHex(messageJson); console.log( - 'Signing randomized message: ', + "Signing randomized message: ", JSON.stringify({ messageJson, messageHex, @@ -116,22 +119,22 @@ function onApiConnectied(api) { ); const start = performance.now(); auth.signHexPayload(messageHex).then( - sig => { + (sig) => { const elapsed = performance.now() - start; console.log(`Signature created in ${elapsed} ms`); - console.log('Signature received: ', sig); - console.log('Verifying signature against the message'); + console.log("Signature received: ", sig); + console.log("Verifying signature against the message"); auth.checkHexPayload(messageHex, sig).then( - r => { - console.log('Signature matches message: ', r); + (r) => { + console.log("Signature matches message: ", r); }, - e => { - console.error('Sig check failed', e); + (e) => { + console.error("Sig check failed", e); } ); }, - err => { - console.error('Sig failed', err); + (err) => { + console.error("Sig failed", err); } ); } @@ -162,50 +165,50 @@ function reduceWasmMultiasset(multiasset, reducer, initValue) { return result; } -cardanoAccessBtn.addEventListener('click', () => { - toggleSpinner('show'); +cardanoAccessBtn.addEventListener("click", () => { + toggleSpinner("show"); const requestIdentification = cardanoAuthCheck.checked; cardano.yoroi.enable({ requestIdentification }).then( function (api) { onApiConnectied(api); }, function (err) { - toggleSpinner('hide'); + toggleSpinner("hide"); alertError(`Error: ${err}`); } ); }); -isEnabledBtn.addEventListener('click', () => { +isEnabledBtn.addEventListener("click", () => { window.cardano.yoroi.isEnabled().then(function (isEnabled) { alertSuccess(`Is Yoroi connection enabled: ${isEnabled}`); }); }); -getNetworkId.addEventListener('click', () => { +getNetworkId.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); } else { - toggleSpinner('show'); - cardanoApi.getNetworkId().then(networkId => { - console.log('[getNetworkId]', networkId); - toggleSpinner('hide'); + toggleSpinner("show"); + cardanoApi.getNetworkId().then((networkId) => { + console.log("[getNetworkId]", networkId); + toggleSpinner("hide"); }); } }); -getAccountBalance.addEventListener('click', () => { +getAccountBalance.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); } else { - toggleSpinner('show'); - const tokenId = '*'; + toggleSpinner("show"); + const tokenId = "*"; cardanoApi.getBalance(tokenId).then(function (balance) { - console.log('[getBalance]', balance); - toggleSpinner('hide'); + console.log("[getBalance]", balance); + toggleSpinner("hide"); let balanceJson = balance; if (isCBOR()) { - if (tokenId !== '*') { + if (tokenId !== "*") { alertSuccess(`Asset Balance: ${balance} (asset: ${tokenId})`); return; } @@ -216,16 +219,22 @@ getAccountBalance.addEventListener('click', () => { (res, asset) => { res[asset.assetId] = asset.amount; return res; - }, {}); - } - alertSuccess(`Account Balance:
${JSON.stringify(balanceJson, null, 2)}
`) - }); - } + }, + {} + ); + } + alertSuccess( + `Account Balance:
${JSON.stringify(balanceJson, null, 2)}
` + ); + }); + } }); function addressesFromCborIfNeeded(addresses) { return isCBOR() - ? addresses.map(a => CardanoWasm.Address.from_bytes(hexToBytes(a)).to_bech32()) + ? addresses.map((a) => + CardanoWasm.Address.from_bytes(hexToBytes(a)).to_bech32() + ) : addresses; } @@ -233,85 +242,95 @@ function addressToCbor(address) { return bytesToHex(CardanoWasm.Address.from_bech32(address).to_bytes()); } -getUnUsedAddresses.addEventListener('click', () => { +getUnUsedAddresses.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); } else { - toggleSpinner('show'); + toggleSpinner("show"); cardanoApi.getUnusedAddresses().then(function (addresses) { - toggleSpinner('hide'); + toggleSpinner("hide"); if (addresses.length === 0) { - alertWarrning('No unused addresses'); + alertWarning("No unused addresses"); return; } addresses = addressesFromCborIfNeeded(addresses); unusedAddresses = addresses; alertSuccess(`Address: `); alertEl.innerHTML = - '

Unused addresses:

' + JSON.stringify(addresses, undefined, 2) + '
'; + "

Unused addresses:

" +
+        JSON.stringify(addresses, undefined, 2) +
+        "
"; }); } }); -getUsedAddresses.addEventListener('click', () => { +getUsedAddresses.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); } else { - toggleSpinner('show'); - cardanoApi.getUsedAddresses({ page: 0, limit: 5 }).then(function (addresses) { - toggleSpinner('hide'); - if (addresses.length === 0) { - alertWarrning('No used addresses'); - return; - } - usedAddresses = addressesFromCborIfNeeded(addresses); - alertSuccess(`Address: ${usedAddresses.concat(',')}`); - alertEl.innerHTML = - '

Used addresses:

' + JSON.stringify(usedAddresses, undefined, 2) + '
'; - }); + toggleSpinner("show"); + cardanoApi + .getUsedAddresses({ page: 0, limit: 5 }) + .then(function (addresses) { + toggleSpinner("hide"); + if (addresses.length === 0) { + alertWarning("No used addresses"); + return; + } + usedAddresses = addressesFromCborIfNeeded(addresses); + alertSuccess(`Address: ${usedAddresses.concat(",")}`); + alertEl.innerHTML = + "

Used addresses:

" +
+          JSON.stringify(usedAddresses, undefined, 2) +
+          "
"; + }); } }); -getChangeAddress.addEventListener('click', () => { +getChangeAddress.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); } else { - toggleSpinner('show'); + toggleSpinner("show"); cardanoApi.getChangeAddress().then(function (address) { - toggleSpinner('hide'); + toggleSpinner("hide"); if (address.length === 0) { - alertWarrning('No change addresses'); + alertWarning("No change addresses"); return; } changeAddress = addressesFromCborIfNeeded([address])[0]; alertSuccess(`Address: `); alertEl.innerHTML = - '

Change address:

' + JSON.stringify(address, undefined, 2) + '
'; + "

Change address:

" +
+        JSON.stringify(address, undefined, 2) +
+        "
"; }); } }); -getRewardAddresses.addEventListener('click', () => { +getRewardAddresses.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); } else { - toggleSpinner('show'); + toggleSpinner("show"); cardanoApi.getRewardAddresses().then(function (addresses) { - toggleSpinner('hide'); + toggleSpinner("hide"); if (addresses.length === 0) { - alertWarrning('No change addresses'); + alertWarning("No change addresses"); return; } addresses = addressesFromCborIfNeeded(addresses); - alertSuccess(`Address: ${addresses.concat(',')}`); + alertSuccess(`Address: ${addresses.concat(",")}`); alertEl.innerHTML = - '

Reward addresses:

' + JSON.stringify(addresses, undefined, 2) + '
'; + "

Reward addresses:

" +
+        JSON.stringify(addresses, undefined, 2) +
+        "
"; }); } }); function mapCborUtxos(cborUtxos) { - return cborUtxos.map(hex => { + return cborUtxos.map((hex) => { const u = CardanoWasm.TransactionUnspentOutput.from_bytes(hexToBytes(hex)); const input = u.input(); const output = u.output(); @@ -338,15 +357,17 @@ function mapCborUtxos(cborUtxos) { function valueRequestObjectToWasmHex(requestObj) { const { amount, assets } = requestObj; - const result = CardanoWasm.Value.new(CardanoWasm.BigNum.from_str(String(amount))); + const result = CardanoWasm.Value.new( + CardanoWasm.BigNum.from_str(String(amount)) + ); if (assets != null) { - if (typeof assets !== 'object') { - throw 'Assets is expected to be an object like `{ [policyId]: { [assetName]: amount } }`'; + if (typeof assets !== "object") { + throw "Assets is expected to be an object like `{ [policyId]: { [assetName]: amount } }`"; } const wmasset = CardanoWasm.MultiAsset.new(); for (const [policyId, assets2] of Object.entries(assets)) { - if (typeof assets2 !== 'object') { - throw 'Assets is expected to be an object like `{ [policyId]: { [assetName]: amount } }`'; + if (typeof assets2 !== "object") { + throw "Assets is expected to be an object like `{ [policyId]: { [assetName]: amount } }`"; } const wassets = CardanoWasm.Assets.new(); for (const [assetName, amount] of Object.entries(assets2)) { @@ -355,7 +376,10 @@ function valueRequestObjectToWasmHex(requestObj) { CardanoWasm.BigNum.from_str(String(amount)) ); } - wmasset.insert(CardanoWasm.ScriptHash.from_bytes(hexToBytes(policyId)), wassets); + wmasset.insert( + CardanoWasm.ScriptHash.from_bytes(hexToBytes(policyId)), + wassets + ); } result.set_multiasset(wmasset); } @@ -364,73 +388,75 @@ function valueRequestObjectToWasmHex(requestObj) { window._getUtxos = function (value) { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } - toggleSpinner('show'); - if (value != null && typeof value !== 'string') { + toggleSpinner("show"); + if (value != null && typeof value !== "string") { value = valueRequestObjectToWasmHex(value); } - cardanoApi.getUtxos(value).then(utxosResponse => { - toggleSpinner('hide'); + cardanoApi.getUtxos(value).then((utxosResponse) => { + toggleSpinner("hide"); if (utxosResponse.length === 0) { - alertWarrning('NO UTXOS'); + alertWarning("NO UTXOS"); } else { utxos = isCBOR() ? mapCborUtxos(utxosResponse) : utxosResponse; alertSuccess( - `

UTxO (${utxos.length}):

` + JSON.stringify(utxos, undefined, 2) + '
' + `

UTxO (${utxos.length}):

` +
+          JSON.stringify(utxos, undefined, 2) +
+          "
" ); } }); }; -getUtxos.addEventListener('click', () => { +getUtxos.addEventListener("click", () => { window._getUtxos(); }); -submitTx.addEventListener('click', () => { +submitTx.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } if (!transactionHex) { - alertError('Should sign tx first'); + alertError("Should sign tx first"); return; } - toggleSpinner('show'); + toggleSpinner("show"); cardanoApi .submitTx(transactionHex) - .then(txId => { - toggleSpinner('hide'); + .then((txId) => { + toggleSpinner("hide"); alertSuccess(`Transaction ${txId} submitted`); }) - .catch(error => { - toggleSpinner('hide'); - alertWarrning(`Transaction submission failed: ${JSON.stringify(error)}`); + .catch((error) => { + toggleSpinner("hide"); + alertWarning(`Transaction submission failed: ${JSON.stringify(error)}`); }); }); -const AMOUNT_TO_SEND = '1000000'; +const AMOUNT_TO_SEND = "1000000"; const SEND_TO_ADDRESS = - 'addr_test1qz8xh9w6f2vdnp89xzqlxnusldhz6kdm4rp970gl8swwjjkr3y3kdut55a40jff00qmg74686vz44v6k363md06qkq0q4lztj0'; + "addr_test1qz8xh9w6f2vdnp89xzqlxnusldhz6kdm4rp970gl8swwjjkr3y3kdut55a40jff00qmg74686vz44v6k363md06qkq0q4lztj0"; -signTx.addEventListener('click', () => { - toggleSpinner('show'); +signTx.addEventListener("click", () => { + toggleSpinner("show"); if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } if (!unsignedTransactionHex) { if (!utxos) { - alertError('Should request utxos first'); + alertError("Should request utxos first"); return; } if (!changeAddress) { - alertError('Should request change address first'); + alertError("Should request change address first"); } const txBuilder = CardanoWasm.TransactionBuilder.new( @@ -439,13 +465,13 @@ signTx.addEventListener('click', () => { // linear fee parameters (a*size + b) .fee_algo( CardanoWasm.LinearFee.new( - CardanoWasm.BigNum.from_str('44'), - CardanoWasm.BigNum.from_str('155381') + CardanoWasm.BigNum.from_str("44"), + CardanoWasm.BigNum.from_str("155381") ) ) - .coins_per_utxo_word(CardanoWasm.BigNum.from_str('34482')) - .pool_deposit(CardanoWasm.BigNum.from_str('500000000')) - .key_deposit(CardanoWasm.BigNum.from_str('2000000')) + .coins_per_utxo_word(CardanoWasm.BigNum.from_str("34482")) + .pool_deposit(CardanoWasm.BigNum.from_str("500000000")) + .key_deposit(CardanoWasm.BigNum.from_str("2000000")) .max_value_size(5000) .max_tx_size(16384) .build() @@ -467,7 +493,8 @@ signTx.addEventListener('click', () => { CardanoWasm.Value.new(CardanoWasm.BigNum.from_str(utxo.amount)) ); - const shelleyOutputAddress = CardanoWasm.Address.from_bech32(SEND_TO_ADDRESS); + const shelleyOutputAddress = + CardanoWasm.Address.from_bech32(SEND_TO_ADDRESS); const shelleyChangeAddress = CardanoWasm.Address.from_bech32(changeAddress); // add output to the tx @@ -495,12 +522,14 @@ signTx.addEventListener('click', () => { tx: unsignedTransactionHex, returnTx, }) - .then(responseHex => { - toggleSpinner('hide'); + .then((responseHex) => { + toggleSpinner("hide"); console.log(`[signTx] response: ${responseHex}`); if (returnTx) { - const signedTx = CardanoWasm.Transaction.from_bytes(hexToBytes(responseHex)); + const signedTx = CardanoWasm.Transaction.from_bytes( + hexToBytes(responseHex) + ); const wit = signedTx.witness_set(); const wkeys = wit.vkeys(); @@ -510,173 +539,203 @@ signTx.addEventListener('click', () => { console.log(`[signTx] wit vkey ${i}:`, { vkBytes: bytesToHex(vk.to_bytes()), vkPubBech: vk.public_key().to_bech32(), - vkPubHashBech: vk.public_key().hash().to_bech32(Bech32Prefix.PAYMENT_KEY_HASH), + vkPubHashBech: vk + .public_key() + .hash() + .to_bech32(Bech32Prefix.PAYMENT_KEY_HASH), }); } transactionHex = responseHex; } else { - const witnessSet = CardanoWasm.TransactionWitnessSet.from_bytes(hexToBytes(responseHex)); - const tx = CardanoWasm.Transaction.from_bytes(hexToBytes(unsignedTransactionHex)); - const transaction = CardanoWasm.Transaction.new(tx.body(), witnessSet, tx.auxiliary_data()); + const witnessSet = CardanoWasm.TransactionWitnessSet.from_bytes( + hexToBytes(responseHex) + ); + const tx = CardanoWasm.Transaction.from_bytes( + hexToBytes(unsignedTransactionHex) + ); + const transaction = CardanoWasm.Transaction.new( + tx.body(), + witnessSet, + tx.auxiliary_data() + ); transactionHex = bytesToHex(transaction.to_bytes()); } - unsignedTransactionHex = null; - alertSuccess('Signing tx succeeded: ' + transactionHex) - - }).catch(error => { - console.error(error) - toggleSpinner('hide') - alertWarrning('Signing tx fails') - }) -}) -showUtxos.addEventListener('click', () => { - + unsignedTransactionHex = null; + alertSuccess("Signing tx succeeded: " + transactionHex); + }) + .catch((error) => { + console.error(error); + toggleSpinner("hide"); + alertWarning("Signing tx fails"); + }); +}); +showUtxos.addEventListener("click", () => { if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } if (!utxos || utxos.length === 0) { - alertError('Should request utxos first'); - return + alertError("Should request utxos first"); + return; } - hideAlert() - renderUtxo() -}) + hideAlert(); + renderUtxo(); +}); -function alertError (text) { - toggleSpinner('hide'); - alertEl.className = 'alert alert-danger overflow-scroll' - alertEl.innerHTML = text +function alertError(text) { + toggleSpinner("hide"); + alertEl.className = "alert alert-danger overflow-scroll"; + alertEl.innerHTML = text; } function alertSuccess(text) { - alertEl.className = 'alert alert-success overflow-scroll' - alertEl.innerHTML = text + alertEl.className = "alert alert-success overflow-scroll"; + alertEl.innerHTML = text; } function hideAlert() { - alertEl.className = 'd-none' - alert.innerHTML = '' + alertEl.className = "d-none"; + alert.innerHTML = ""; } -function alertWarrning(text) { - alertEl.className = 'alert alert-warning' - alertEl.innerHTML = text +function alertWarning(text) { + alertEl.className = "alert alert-warning"; + alertEl.innerHTML = text; } -function toggleSpinner(status){ - if(status === 'show') { - spinner.className = 'spinner-border' - alertEl.className = 'd-none' - } else { - spinner.className = 'd-none' - } +function toggleSpinner(status) { + if (status === "show") { + spinner.className = "spinner-border"; + alertEl.className = "d-none"; + } else { + spinner.className = "d-none"; + } } function toggleConnectionUI(status) { - if (status === 'button') { - connectionStatus.classList.add('d-none'); - cardanoAccessBtnRow.classList.remove('d-none'); + if (status === "button") { + connectionStatus.classList.add("d-none"); + cardanoAccessBtnRow.classList.remove("d-none"); } else { - cardanoAccessBtnRow.classList.add('d-none'); - connectionStatus.classList.remove('d-none'); + cardanoAccessBtnRow.classList.add("d-none"); + connectionStatus.classList.remove("d-none"); } } function selectUtxo(e) { - if (!e.target.id) { - alertError("Invalid idx") - return - } - selectedUtxoIdx = e.target.id - hideAlert() - renderUtxo() + if (!e.target.id) { + alertError("Invalid idx"); + return; + } + selectedUtxoIdx = e.target.id; + hideAlert(); + renderUtxo(); } function renderUtxo() { - let utxosHTML = '' - for(let idx in utxos) { - const utxo = utxos[idx] - utxosHTML+= ` -
  • + let utxosHTML = ""; + for (let idx in utxos) { + const utxo = utxos[idx]; + utxosHTML += ` +
  • ${utxo.utxo_id.slice(0, 50)}

    ${utxo.amount}
  • - ` + `; } utxosHTML += ` - ` - utxosContainer.innerHTML = utxosHTML - utxosContainer.classList.remove('d-none') - utxosContainer.classList.add('d-block', 'list-group', 'list-group-numbered', 'mb-5') + `; + utxosContainer.innerHTML = utxosHTML; + utxosContainer.classList.remove("d-none"); + utxosContainer.classList.add( + "d-block", + "list-group", + "list-group-numbered", + "mb-5" + ); // Add select utxo handler for each list item - document.querySelectorAll('.utxo-item').forEach(el => { - el.addEventListener('click', selectUtxo) - }) + document.querySelectorAll(".utxo-item").forEach((el) => { + el.addEventListener("click", selectUtxo); + }); // Add event handler for create tx button - document.querySelector('#create-tx').addEventListener('click', createTxHandler) + document + .querySelector("#create-tx") + .addEventListener("click", createTxHandler); } - function createTxHandler(e) { - toggleSpinner('show'); + toggleSpinner("show"); if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } if (!utxos || utxos.length === 0) { - alertError('Should request utxos first'); + alertError("Should request utxos first"); return; } if (!usedAddresses || usedAddresses.length === 0) { - alertError('Should request used addresses first'); + alertError("Should request used addresses first"); return; } const selectedUtxo = utxos[selectedUtxoIdx]; if (!selectedUtxo) { - alertError('Failed to select a random utxo from the available list!'); + alertError("Failed to select a random utxo from the available list!"); return; } - console.log('[createTx] Including random utxo input: ', selectedUtxo); + console.log("[createTx] Including random utxo input: ", selectedUtxo); const usedAddress = usedAddresses[0]; - const keyHash = CardanoWasm.BaseAddress.from_address(CardanoWasm.Address.from_bech32(usedAddress)) + const keyHash = CardanoWasm.BaseAddress.from_address( + CardanoWasm.Address.from_bech32(usedAddress) + ) .payment_cred() .to_keyhash(); const keyHashBech = keyHash.to_bech32(Bech32Prefix.PAYMENT_KEY_HASH); const scripts = CardanoWasm.NativeScripts.new(); - scripts.add(CardanoWasm.NativeScript.new_script_pubkey(CardanoWasm.ScriptPubkey.new(keyHash))); - scripts.add(CardanoWasm.NativeScript.new_timelock_start(CardanoWasm.TimelockStart.new(42))); + scripts.add( + CardanoWasm.NativeScript.new_script_pubkey( + CardanoWasm.ScriptPubkey.new(keyHash) + ) + ); + scripts.add( + CardanoWasm.NativeScript.new_timelock_start( + CardanoWasm.TimelockStart.new(42) + ) + ); - const mintScript = CardanoWasm.NativeScript.new_script_all(CardanoWasm.ScriptAll.new(scripts)); + const mintScript = CardanoWasm.NativeScript.new_script_all( + CardanoWasm.ScriptAll.new(scripts) + ); const mintScriptHex = bytesToHex(mintScript.to_bytes()); function convertAssetNameToHEX(name) { return bytesToHex(name); } - const tokenAssetName = 'V42'; + const tokenAssetName = "V42"; const nftAssetName = `V42/NFT#${Math.floor(Math.random() * 1000000000)}`; const tokenAssetNameHex = convertAssetNameToHEX(tokenAssetName); const nftAssetNameHex = convertAssetNameToHEX(nftAssetName); const expectedPolicyId = bytesToHex(mintScript.hash().to_bytes()); - console.log('[createTx] Including mint request: ', { + console.log("[createTx] Including mint request: ", { keyHashBech, mintScriptHex, assetNameHex: tokenAssetNameHex, @@ -686,7 +745,7 @@ function createTxHandler(e) { const outputHex = bytesToHex( CardanoWasm.TransactionOutput.new( CardanoWasm.Address.from_bech32(selectedUtxo.receiver), - CardanoWasm.Value.new(CardanoWasm.BigNum.from_str('1000000')), + CardanoWasm.Value.new(CardanoWasm.BigNum.from_str("1000000")) ).to_bytes() ); @@ -720,14 +779,24 @@ function createTxHandler(e) { // noinspection PointlessBooleanExpressionJS if (nativeScriptInputUtxoId != null) { const nscripts = CardanoWasm.NativeScripts.new(); - nscripts.add(CardanoWasm.NativeScript.new_timelock_start(CardanoWasm.TimelockStart.new(1234))); - nscripts.add(CardanoWasm.NativeScript.new_timelock_start(CardanoWasm.TimelockStart.new(1))); + nscripts.add( + CardanoWasm.NativeScript.new_timelock_start( + CardanoWasm.TimelockStart.new(1234) + ) + ); + nscripts.add( + CardanoWasm.NativeScript.new_timelock_start( + CardanoWasm.TimelockStart.new(1) + ) + ); const nativeScript = CardanoWasm.NativeScript.new_script_all( CardanoWasm.ScriptAll.new(nscripts) ); const scriptHash = nativeScript.hash(); - console.log(`[createTx] Native script hash: ${bytesToHex(scriptHash.to_bytes())}`); + console.log( + `[createTx] Native script hash: ${bytesToHex(scriptHash.to_bytes())}` + ); const nativeScriptAddress = CardanoWasm.EnterpriseAddress.new( 0, CardanoWasm.StakeCredential.from_scripthash(scriptHash) @@ -747,11 +816,15 @@ function createTxHandler(e) { // noinspection PointlessBooleanExpressionJS if (plutusScriptInputUtxoId != null || createPlutusTarget) { const plutusScript = CardanoWasm.PlutusScript.from_bytes( - hexToBytes('4e4d01000033222220051200120011') + hexToBytes("4e4d01000033222220051200120011") ); const plutusScriptHash = plutusScript.hash(); - console.log(`[createTx] Plutus script hash: ${bytesToHex(plutusScriptHash.to_bytes())}`); + console.log( + `[createTx] Plutus script hash: ${bytesToHex( + plutusScriptHash.to_bytes() + )}` + ); const plutusScriptAddress = CardanoWasm.EnterpriseAddress.new( 0, CardanoWasm.StakeCredential.from_scripthash(plutusScriptHash) @@ -760,8 +833,12 @@ function createTxHandler(e) { .to_bech32(); console.log(`[createTx] Plutus script address: ${plutusScriptAddress}`); - const datum = CardanoWasm.PlutusData.new_empty_constr_plutus_data(CardanoWasm.BigNum.zero()); - const datumHash = bytesToHex(CardanoWasm.hash_plutus_data(datum).to_bytes()); + const datum = CardanoWasm.PlutusData.new_empty_constr_plutus_data( + CardanoWasm.BigNum.zero() + ); + const datumHash = bytesToHex( + CardanoWasm.hash_plutus_data(datum).to_bytes() + ); console.log(`[createTx] Plutus datum hash: ${datumHash}`); if (createPlutusTarget) { @@ -774,10 +851,12 @@ function createTxHandler(e) { const redeemer = CardanoWasm.Redeemer.new( CardanoWasm.RedeemerTag.new_spend(), CardanoWasm.BigNum.zero(), - CardanoWasm.PlutusData.new_empty_constr_plutus_data(CardanoWasm.BigNum.zero()), + CardanoWasm.PlutusData.new_empty_constr_plutus_data( + CardanoWasm.BigNum.zero() + ), CardanoWasm.ExUnits.new( - CardanoWasm.BigNum.from_str('1700'), - CardanoWasm.BigNum.from_str('476468') + CardanoWasm.BigNum.from_str("1700"), + CardanoWasm.BigNum.from_str("476468") ) ); @@ -795,13 +874,13 @@ function createTxHandler(e) { if (includeDefaultTargets) { includeTargets.push({ address: targetAddress, - value: '2000000', + value: "2000000", dataHash: targetDataHash, mintRequest: [ { script: mintScriptHex, assetName: tokenAssetNameHex, - amount: '42', + amount: "42", }, { script: mintScriptHex, @@ -812,13 +891,13 @@ function createTxHandler(e) { json: JSON.stringify({ name: nftAssetName, description: `V42 NFT Collection`, - mediaType: 'image/png', - image: 'ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw', + mediaType: "image/png", + image: "ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw", files: [ { name: nftAssetName, - mediaType: 'image/png', - src: 'ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw', + mediaType: "image/png", + src: "ipfs://QmRhTTbUrPYEw3mJGGhQqQST9k86v1DPBiTTWJGKDJsVFw", }, ], }), @@ -836,17 +915,18 @@ function createTxHandler(e) { }; if (includeAssetTargets) { - const utxosWithAssets = utxos.filter(u => u.assets.length > 0); - const utxoWithAssets = utxosWithAssets[Math.floor(Math.random() * utxosWithAssets.length)]; + const utxosWithAssets = utxos.filter((u) => u.assets.length > 0); + const utxoWithAssets = + utxosWithAssets[Math.floor(Math.random() * utxosWithAssets.length)]; if (utxoWithAssets) { const asset = utxoWithAssets.assets[0]; - console.log('[createTx] Including asset:', asset); + console.log("[createTx] Including asset:", asset); txReq.includeTargets.push({ // do not specify value, the connector will use minimum value address: selectedUtxo.receiver, assets: { - [asset.assetId]: '1', + [asset.assetId]: "1", }, ensureRequiredMinimalValue: true, }); @@ -855,54 +935,56 @@ function createTxHandler(e) { cardanoApi.experimental .createTx(txReq, true) - .then(txHex => { - toggleSpinner('hide'); + .then((txHex) => { + toggleSpinner("hide"); alertSuccess(`

    Creating tx succeeds: ${txHex}

    `); unsignedTransactionHex = txHex; }) - .catch(error => { + .catch((error) => { console.error(error); - toggleSpinner('hide'); - alertWarrning('Creating tx fails'); + toggleSpinner("hide"); + alertWarning("Creating tx fails"); }); -}); +} -getCollateralUtxos.addEventListener('click', () => { - toggleSpinner('show'); +getCollateralUtxos.addEventListener("click", () => { + toggleSpinner("show"); if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } - const amount = '4900000'; + const amount = "4900000"; cardanoApi .getCollateralUtxos( - Buffer.from(CardanoWasm.Value.new(CardanoWasm.BigNum.from_str(amount)).to_bytes()).toString( - 'hex' - ) + Buffer.from( + CardanoWasm.Value.new(CardanoWasm.BigNum.from_str(amount)).to_bytes() + ).toString("hex") ) - .then(utxosResponse => { - toggleSpinner('hide'); + .then((utxosResponse) => { + toggleSpinner("hide"); let utxos = isCBOR() ? mapCborUtxos(utxosResponse) : utxosResponse; alertSuccess( `

    Collateral UTxO (${utxos.length}):

    ` +
               JSON.stringify(utxos, undefined, 2) +
    -          '
    ' + "" ); }) - .catch(error => { + .catch((error) => { console.error(error); - toggleSpinner('hide'); - alertWarrning(`Getting collateral UTXOs tx fails: ${JSON.stringify(error)}`); + toggleSpinner("hide"); + alertWarning( + `Getting collateral UTXOs tx fails: ${JSON.stringify(error)}` + ); }); }); -signData.addEventListener('click', () => { - toggleSpinner('show'); +signData.addEventListener("click", () => { + toggleSpinner("show"); if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } @@ -912,7 +994,7 @@ signData.addEventListener('click', () => { } else if (unusedAddresses && unusedAddresses.length > 0) { address = unusedAddresses[0]; } else { - alertError('Should request used or unused addresses first'); + alertError("Should request used or unused addresses first"); return; } @@ -920,34 +1002,34 @@ signData.addEventListener('click', () => { address = addressToCbor(address); } - const payload = document.querySelector('#sign-data-payload').value; + const payload = document.querySelector("#sign-data-payload").value; let payloadHex; - if (payload.startsWith('0x')) { - payloadHex = Buffer.from(payload.replace('^0x', ''), 'hex').toString('hex'); + if (payload.startsWith("0x")) { + payloadHex = Buffer.from(payload.replace("^0x", ""), "hex").toString("hex"); } else { - payloadHex = Buffer.from(payload, 'utf8').toString('hex'); + payloadHex = Buffer.from(payload, "utf8").toString("hex"); } - console.log('[signData][address] ', address); + console.log("[signData][address] ", address); cardanoApi .signData(address, payloadHex) - .then(sig => { - alertSuccess('Signature:' + JSON.stringify(sig)); + .then((sig) => { + alertSuccess("Signature:" + JSON.stringify(sig)); }) - .catch(error => { + .catch((error) => { console.error(error); alertError(error.info); }) .then(() => { - toggleSpinner('hide'); + toggleSpinner("hide"); }); }); -getNFTs.addEventListener('click', async () => { - toggleSpinner('show'); +getNFTs.addEventListener("click", async () => { + toggleSpinner("show"); if (!accessGranted) { - alertError('Should request access first'); + alertError("Should request access first"); return; } @@ -958,69 +1040,41 @@ getNFTs.addEventListener('click', async () => { console.error(error); alertError(error.message); } - toggleSpinner('hide'); -}) - -function alertError(text) { - toggleSpinner('hide'); - alertEl.className = 'alert alert-danger'; - alertEl.innerHTML = text; -} - -function alertSuccess(text) { - alertEl.className = 'alert alert-success'; - alertEl.innerHTML = text; -} - -function alertWarrning(text) { - alertEl.className = 'alert alert-warning'; - alertEl.innerHTML = text; -} + toggleSpinner("hide"); +}); -function renderJonsResponse (title, response) { +function renderJonsResponse(title, response) { alertSuccess( - `

    ${title}:

    ` + JSON.stringify(response, undefined, 2) + '
    ' - ) -} - -function toggleSpinner(status) { - if (status === 'show') { - spinner.className = 'spinner-border'; - alertEl.className = 'd-none'; - } else { - spinner.className = 'd-none'; - } -} - -function toggleConnectionUI(status) { - if (status === 'button') { - connectionStatus.classList.add('d-none'); - cardanoAccessBtnRow.classList.remove('d-none'); - } else { - cardanoAccessBtnRow.classList.add('d-none'); - connectionStatus.classList.remove('d-none'); - } + `

    ${title}:

    ` +
    +      JSON.stringify(response, undefined, 2) +
    +      "
    " + ); } window.onload = () => { - if (typeof window.cardano === 'undefined') { - alertError('Cardano API not found'); + if (typeof window.cardano === "undefined") { + alertError("Cardano API not found"); } else { - console.log('Cardano API detected, checking connection status'); - cardano.yoroi.enable({ requestIdentification: true, onlySilent: true }).then( - api => { - console.log('successful silent reconnection'); - onApiConnectied(api); - }, - err => { - if (String(err).includes('onlySilent:fail')) { - console.log('no silent re-connection available'); - } else { - console.error('Silent reconnection failed for unknown reason!', err); + console.log("Cardano API detected, checking connection status"); + cardano.yoroi + .enable({ requestIdentification: true, onlySilent: true }) + .then( + (api) => { + console.log("successful silent reconnection"); + onApiConnectied(api); + }, + (err) => { + if (String(err).includes("onlySilent:fail")) { + console.log("no silent re-connection available"); + } else { + console.error( + "Silent reconnection failed for unknown reason!", + err + ); + } + toggleSpinner("hide"); + toggleConnectionUI("button"); } - toggleSpinner('hide'); - toggleConnectionUI('button'); - } - ); + ); } };