Skip to content

Commit

Permalink
web interface should work for many wallets now
Browse files Browse the repository at this point in the history
  • Loading branch information
logicalmechanism committed Dec 18, 2024
1 parent 3fff001 commit 5c7c2ba
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 43 deletions.
21 changes: 21 additions & 0 deletions seedelf-cli/static/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,25 @@ section {
#status {
max-width: 60%;
word-wrap: break-word;
}

select {
padding: 16px;
font-size: 16px;
background-color: #f9f9f9;
color: #333;
outline: none;
cursor: pointer;
text-align: center;
text-align-last: center;
}

/* Add hover and focus effects */
select:hover {
background-color: #f0f0f0;
}

select:focus {
border-color: #007bff;
box-shadow: 0 0 5px rgba(0, 123, 255, 0.5);
}
21 changes: 13 additions & 8 deletions seedelf-cli/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
<head>
<title>Seedelf Web Interface</title>
<link rel="icon" href="favicon.ico" type="image/x-icon">

<!-- Make it look pretty inside of index.css -->
<link rel="stylesheet" href="index.css">

<!-- Placeholder for injecting dynamic text -->
<script id="injected-data" type="application/json">
{ "message": "ACAB000000000000" }
Expand All @@ -24,21 +24,26 @@
<body>
<nav class="nav-bar">
<h1 class="nav-left">Welcome to Seedelf Web Interface!</h1>
<h3 class="nav-right">Currently only Eternl is supported.</h3>
<!-- <h3 class="nav-right">Currently only Eternl is supported.</h3> -->
<div class="nav-right">
<select id="wallet_dropdown" name="options">
<option value="" selected>Connect A Wallet</option>
</select>
</div>
</nav>

<header class="centered">
<h4>This page will prompt you to sign a transaction. This allows the Seedelf wallet to interact with a CIP30 wallet when applicable.</h4>
<h4>This page will prompt you to sign a transaction with the wallet of your choice.</h4>
</header>

<main>
<section class="centered">
<p id="status" class="centered">Waiting for wallet to load...</p>
<a id="tx_link" href="" class="link-button" target="_blank" rel="noopener noreferrer" ></a>
<a id="tx_link" href="" class="link-button" target="_blank" rel="noopener noreferrer"></a>
</section>

<section>
<p>Transaction CBOR Being Signed:</p>
<p>Transaction CBOR:</p>
<code id="tx_cbor"></code>
</section>
</main>
Expand Down
123 changes: 88 additions & 35 deletions seedelf-cli/static/index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,31 @@

async function initializePage() {
// get the installed wallets for the user to select
const cardano = await waitForCardano();
populateWalletDropdown(cardano);

// Retrieve dynamic data from the injected script
const injectedScript = document.getElementById("injected-data");
const injectedNetworkScript = document.getElementById("injected-network-data");
const data = JSON.parse(injectedScript.textContent || "{}");
const network = JSON.parse(injectedNetworkScript.textContent || "");
console.log("Dynamic data loaded:", data.message);
console.log("Dynamic network loaded:", network.network);
const injectedData = JSON.parse(injectedScript.textContent || "{}");
const injectedNetwork = JSON.parse(injectedNetworkScript.textContent || "");

// we can change the status with this element
const statusElement = document.getElementById("status");
const txLinkElement = document.getElementById("tx_link");

// we can push tx cbor for easy viewing here
const txCborElement = document.getElementById("tx_cbor");
txCborElement.textContent = data.message;
txCborElement.textContent = injectedData.message;

// we need to wait for th wallet, enable it, then sign the injected data
// we need to wait for the wallet, enable it, then sign the injected data
try {
const walletObject = await waitForWallet();
const wallet = await walletObject.enable();

// we need to make sure that the wallet is actually on the correct network
const network_int = await wallet.getNetworkId();
if (network.network === "preprod.") {
if (injectedNetwork.network === "preprod.") {
if (network_int !== 0) {
statusElement.textContent = "Wallet is not using pre-production. Please switch to the pre-production network and try again.";
return;
Expand All @@ -34,52 +37,102 @@ async function initializePage() {
}
}

// the wallet should be enabled and on the correct network
statusElement.textContent = "Wallet connected successfully!";

const sig_part = await wallet.signTx(data.message);
console.log("Wallet Sig:", sig_part);

let sig;
let complete_tx;
if (data.message.indexOf("a105") === -1) {
complete_tx = data.message.replace("a0f5f6", sig_part + "f5f6")
} else {
// smart contract exists as there is a redeemer
sig = "a2" + sig_part.slice(2);
const redeemer_part = data.message.slice(data.message.indexOf("a105"));
complete_tx = data.message.replace(redeemer_part, sig) + redeemer_part.slice(2);
}

console.log("Tx:", complete_tx);
let tx_hash = await wallet.submitTx(complete_tx);
console.log("Tx Hash:", tx_hash);

txLinkElement.href = "https://" + network.network + "cardanoscan.io/transaction/" + tx_hash; // Set the href attribute
txLinkElement.textContent = "View Transaction On Cardanoscan";

statusElement.textContent = "Transaction successfully submitted! It will take a few moments to hit the chain. Please close this tab and crtl-c the server in the terminal. The transaction can be viewed on Cardanoscan by clicking the View Transaction On Cardanoscan button.";
try {
const sig_part = await wallet.signTx(injectedData.message);

// initialize these as they will be built out here
let sig;
let complete_tx;
if (injectedData.message.indexOf("a105") === -1) {
complete_tx = injectedData.message.replace("a0f5f6", sig_part + "f5f6")
} else {
// smart contract exists as there is a redeemer
sig = "a2" + sig_part.slice(2);
const redeemer_part = injectedData.message.slice(injectedData.message.indexOf("a105"));
complete_tx = injectedData.message.replace(redeemer_part, sig) + redeemer_part.slice(2);
}

// lets use cardanoscan to view it
let tx_hash = await wallet.submitTx(complete_tx);
txLinkElement.href = "https://" + injectedNetwork.network + "cardanoscan.io/transaction/" + tx_hash; // Set the href attribute
txLinkElement.textContent = "View Transaction On Cardanoscan";

statusElement.textContent = "Transaction successfully submitted! It will take a few moments to hit the chain. Please close this tab and crtl-c the server in the terminal. The transaction can be viewed on Cardanoscan by clicking the View Transaction On Cardanoscan button.";
} catch (error) {
statusElement.textContent = "Failed to connect wallet: " + error.message;
}
} catch (error) {
console.error("Failed to enable wallet:", error);
statusElement.textContent = "Failed to connect wallet: " + error.message;
}
}

async function waitForWallet() {
return new Promise((resolve, reject) => {

let attempts = 0;
const maxAttempts = 20;
const maxAttempts = 3000;
let walletName = "";

const interval = setInterval(() => {
if (window.cardano && window.cardano.eternl) {
clearInterval(interval);
resolve(window.cardano.eternl);
const interval = setInterval(async () => {
if (window.cardano && window.cardano[walletName]) {
if (await window.cardano[walletName].isEnabled() === true) {
clearInterval(interval);
resolve(window.cardano[walletName]);
} else {
const statusElement = document.getElementById("status");
statusElement.textContent = "Wallet is not enabled. Please try a different wallet.";
}
} else if (attempts >= maxAttempts) {
clearInterval(interval);
reject(new Error("Wallet not found after waiting."));
}
attempts++;

// we let the user select a wallet to use first
const walletDropdownElement = document.getElementById("wallet_dropdown");
walletName = walletDropdownElement.value;

}, 100);
});
}

async function waitForCardano() {
return new Promise((resolve, reject) => {
let attempts = 0;
const maxAttempts = 3000; // Adjust attempts as needed
const interval = setInterval(() => {
if (window.cardano && Object.keys(window.cardano).length > 0) {
clearInterval(interval);
resolve(window.cardano); // Resolve with the wallets
} else if (attempts >= maxAttempts) {
clearInterval(interval);
reject(new Error("Cardano wallets not found after waiting."));
}
attempts++;
}, 100); // Check every 100ms
});
}

function populateWalletDropdown(cardano) {
// auto populate the dropdown with the installed wallets
const walletDropdown = document.getElementById('wallet_dropdown');
for (const key in cardano) {
try {
const _wallet = window.cardano[key];
if (_wallet === undefined) continue;
if (_wallet.name === undefined) continue;
if (_wallet.icon === undefined) continue;
if (_wallet.apiVersion === undefined) continue;

const option = document.createElement('option');
option.value = key;
option.textContent = _wallet.name.charAt(0).toUpperCase() + _wallet.name.slice(1); // Capitalize first letter
walletDropdown.appendChild(option);
} catch (e) {}
}
}

document.addEventListener("DOMContentLoaded", initializePage);

0 comments on commit 5c7c2ba

Please sign in to comment.