Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,9 @@ <h5 class="text-cyber-yellow">although all entities encountered may not be.</h5>
<details class="cyberpunk-panel bg-zinc-800/80 rounded-lg p-4 border border-cyber-neon text-xs text-zinc-300">
<summary class="text-cyan-300 cursor-pointer">What is a Lockb0x Sigil?</summary>
<div class="mt-2">
<p><span class="text-cyan-300"><a href="https://lamina1.com" target="_blank" rel="noopener"
class="cyberpunk-link underline text-cyan-300 hover:text-cyan-200">Your Sigil NFT is a symbol or icon is
your key to Node_Zero. It is used to unlock content and to represent your entity and its activities in
<p><span class="text-cyan-300">Your lockb0x Sigil NFT is
your key to Node_Zero.<br/>
It is used to unlock content and to represent your entity and its activities in
Node_Zero. It is used as a visual identifier and the unique attibutes you set by customizing it along with
other metadfata are used for various randomness and entropy characteristics within Node_ero
experiences.</span>.
Expand Down
8 changes: 4 additions & 4 deletions js/header-logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ async function updateCarrierIndicator() {

if (isMetaMask && isConnected && account) {
// Check PoH and NFT status using utils.js if available
if (window.lockb0xUtils && window.lockb0xUtils.isPohVerifiedForAddress) {
if (window.lockb0xUtils && window.lockb0xUtils.checkPohStatus) {
try {
pohVerified = window.lockb0xUtils.isPohVerifiedForAddress(account);
pohVerified = await window.lockb0xUtils.checkPohStatus(account);
} catch { pohVerified = false; }
}
if (window.lockb0xUtils && window.lockb0xUtils.checkOwnershipForAddress) {
Expand Down Expand Up @@ -181,7 +181,7 @@ async function updateCarrierIndicator() {
connectBtn._handlerSet = true;
}
// lockb0x utils unavailable
if (isConnected && (!window.lockb0xUtils || !window.lockb0xUtils.checkOwnershipForAddress || !window.lockb0xUtils.isPohVerifiedForAddress)) {
if (isConnected && (!window.lockb0xUtils || !window.lockb0xUtils.checkOwnershipForAddress || !window.lockb0xUtils.checkPohStatus)) {
console.log('Advanced features unavailable (lockb0x not loaded).');
}
}
Expand All @@ -201,7 +201,7 @@ function waitForUtilsAndInit(retryCount) {
isMetaMask = (typeof window.ethereum !== 'undefined' && window.ethereum.isMetaMask);


if (window.lockb0xUtils && window.lockb0xUtils.checkOwnershipForAddress && window.lockb0xUtils.isPohVerifiedForAddress) {
if (window.lockb0xUtils && window.lockb0xUtils.checkOwnershipForAddress && window.lockb0xUtils.checkPohStatus) {
updateCarrierIndicator();
if (window.ethereum) {
window.ethereum.on && window.ethereum.on('accountsChanged', updateCarrierIndicator);
Expand Down
4 changes: 2 additions & 2 deletions keya/chapter1a.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ <h1 class="title-font text-3xl md:text-5xl font-bold glow-cyan">Node_Zero :: The
checked /><span>Auto-Scroll</span></label>
<div class="hidden md:flex items-center gap-2">
<span class="opacity-70">Speed</span>
<input id="rng-speed" type="range" min="10" max="60" value="18" />
<input id="rng-speed" title="Typing Speed" type="range" min="10" max="60" value="18" />
</div>
</div>
</section>
Expand Down Expand Up @@ -81,7 +81,7 @@ <h2 class="title-font text-xl glow-green">Intel Unlocked</h2>

});
</script>

<script src="/js/chapter1a-game.js"></script>
</body>

Expand Down
2 changes: 1 addition & 1 deletion lockb0x/contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export async function hasLockb0xSigilNFT(address) {
if (chainId !== lineaSepoliaChainId) {
return false;
}
const provider = new ethers.providers.Web3Provider(window.ethereum);
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(CONTRACT_ADDRESS, ABI, provider);
try {
const balance = await contract.balanceOf(address);
Expand Down
85 changes: 46 additions & 39 deletions lockb0x/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,36 +109,31 @@
</div>
</main>

<script src="../js/main.js"></script>
<script src="../lockb0x/contract-config.js"></script>
<script src="../js/header-loader.js"></script>
<script type="module" src="../lockb0x-utils-global.js"></script>

<script type="module" src="preview.js"></script>
<script type="module" src="cbor.js"></script>
<script type="module" src="mint.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
<script src="../js/main.js"></script>
<script src="../lockb0x/contract-config.js"></script>
<script src="../js/header-loader.js"></script>

<script type="module" src="../lockb0x-utils-global.js"></script>




<!-- Wallet/PoH check and dynamic minting logic (UI always visible) -->
<script type="module">

import {
isMetaMaskInstalled,
isMetaMaskConnected,
getWalletConnected,
isWalletConnectionExpired,
isPohVerifiedForAddress,
getProvider,
registerWalletEventHandlers
registerWalletEventHandlers,
getTokenGatingState,
connectWallet,
ensureLineaSepolia
} from './utils.js';


let pohStatus = false;
let walletAddress = null;

async function updateMintUI() {
const mintBtn = document.getElementById('mintBtn');
const mintStatus = document.getElementById('mintStatus');
Expand All @@ -149,18 +144,11 @@
const connectBtn = document.getElementById('connectMetaMaskBtn');

// Check wallet and PoH status
pohStatus = false;
walletAddress = null;
let connected = false;
if (isMetaMaskInstalled()) {
connected = await isMetaMaskConnected();
if (connected) {
walletAddress = getWalletConnected();
if (walletAddress && !isWalletConnectionExpired()) {
pohStatus = await isPohVerifiedForAddress(walletAddress);
}
}
}
const gating = await getTokenGatingState();
const connected = gating.connected;
const walletAddress = gating.wallet;
const pohStatus = gating.poh;
const gatingError = gating.error;

// Show/hide Connect MetaMask button
if (!isMetaMaskInstalled()) {
Expand All @@ -174,11 +162,22 @@
// Always enable mint button if wallet is connected and on correct network
let provider, network;
let onLinea = false;
let switchAttempted = false;
if (connected) {
try {
provider = getProvider();
network = await provider.getNetwork();
onLinea = (network.chainId === 59141n);
if (!onLinea) {
// Attempt to switch network
switchAttempted = true;
await ensureLineaSepolia();
if (switched) {
// Re-check network after switch
network = await provider.getNetwork();
onLinea = (network.chainId === 59141n);
}
}
} catch {}
}

Expand Down Expand Up @@ -216,6 +215,9 @@
} else if (!onLinea) {
web3Info.style.display = '';
web3Info.textContent = 'Switch to Linea Sepolia network in MetaMask.';
} else if (gatingError) {
web3Info.style.display = '';
web3Info.textContent = gatingError;
} else {
web3Info.style.display = 'none';
web3Info.textContent = '';
Expand All @@ -227,10 +229,10 @@
// Connect MetaMask button logic
document.getElementById('connectMetaMaskBtn').addEventListener('click', async (evt) => {
evt.preventDefault();
if (window.ethereum) {
try {
await window.ethereum.request({ method: 'eth_requestAccounts' });
} catch (err) {}
try {
await connectWallet();
} catch (err) {
console.error(err);
}
await updateMintUI();
});
Expand All @@ -249,19 +251,24 @@
const tierSelect = document.getElementById('tierSelect');
const tier = tierSelect ? tierSelect.value : 'standard';
// Check wallet and PoH again
let connected = isMetaMaskInstalled() && await isMetaMaskConnected();
let provider, network, onLinea = false;
if (connected) {
try {
provider = getProvider();
network = await provider.getNetwork();
onLinea = (network.chainId === 59141n);
} catch {}
}
const gating = await getTokenGatingState();
const connected = gating.connected;
const pohStatus = gating.poh;

if (!connected) {
mintStatus.textContent = 'Please connect MetaMask.';
return;
}

let provider, network, onLinea = false;
try {
provider = await ensureLineaSepolia();
network = await provider.getNetwork();
onLinea = (network.chainId === 59141n);
} catch (err) {
mintStatus.textContent = err?.message || 'Please switch to Linea Sepolia network.';
return;
}
if (!onLinea) {
mintStatus.textContent = 'Please switch to Linea Sepolia network.';
return;
Expand Down
52 changes: 52 additions & 0 deletions lockb0x/mint-poh.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { getSigner, getContract, readParams } from "./utils.js";
import { getPohSignatureFromAPI } from "./session.js";

/**
* Mint NFT using PoH free mint
* @param {string} address - Wallet address
* @param {string} tier - Minting tier
* @param {HTMLElement} statusElement - Element to display status messages
*/
export async function mintPoh(address, tier, statusElement) {
try {
if (statusElement) {
statusElement.textContent = "Requesting PoH signature…";
statusElement.style.color = "#ccc";
}

const signer = await getSigner();
const contract = await getContract();

// Fetch signature from PoH Signer API
const signatureHex = await getPohSignatureFromAPI(address);
if (!signatureHex) {
throw new Error("Failed to retrieve PoH signature. Please ensure you have completed Proof of Humanity verification.");
}

// Convert hex string to bytes for contract
const signature = window.ethers.getBytes(signatureHex);

const params = readParams(tier);

if (statusElement) {
statusElement.textContent = "Submitting PoH transaction…";
}

const tx = await contract.mintPoHFree(params, signature);
const receipt = await tx.wait();

if (statusElement) {
statusElement.textContent = `PoH mint successful! Tx: ${receipt.hash}`;
statusElement.style.color = "#8f8";
}
}
catch (err) {
console.error("PoH mint error:", err);
const errorMsg = err?.reason || err?.message || "PoH mint failed.";
if (statusElement) {
statusElement.textContent = errorMsg;
statusElement.style.color = "#f66";
}
throw err;
}
}
55 changes: 27 additions & 28 deletions lockb0x/mint.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// mint.js — FINAL CLEAN VERSION
// mint.js - NFT minting logic for Lockb0x
// ---------------------------------------------------------------------
import {
connectWallet,
Expand All @@ -11,11 +11,12 @@ import {
registerWalletEventHandlers,
setDebugMode,
setGatingErrorHandler,
isWalletConnectionExpired,
isPohVerifiedForAddress,
getPohSignature,
checkPohAndPersist
checkPohStatus
} from "./utils.js";
import { mintPoh } from "./mint-poh.js";



// Enable debug mode for development (set to false in production)
setDebugMode(true);

Expand Down Expand Up @@ -107,11 +108,14 @@ mintBtn.addEventListener("click", async () => {
try {
// Centralized gating check
const { connected, wallet, error } = await getTokenGatingState();
if (!connected || !wallet || isWalletConnectionExpired()) {
if (!connected || !wallet) {
let msg = error ? `Mint blocked: ${error}` : "Mint blocked: Wallet connection required.";
if (isWalletConnectionExpired()) {
msg = "Mint blocked: Wallet connection expired. Please reconnect your wallet.";
if(!connected) {
msg = "Mint blocked: Wallet not connected.";
} else if (!wallet) {
msg = "Mint blocked: Wallet address not found.";
}

mintStatus.textContent = msg;
mintStatus.style.color = "#f66";
mintBtn.disabled = false;
Expand Down Expand Up @@ -142,29 +146,24 @@ mintBtn.addEventListener("click", async () => {
let tx;
let codeHash = null;

if (tier === "standard" && isPohVerifiedForAddress(wallet)) {
let pohSignature = getPohSignature(wallet);
let pohPayload = localStorage.getItem(`poh_payload_${wallet.toLowerCase()}`);
// Validate PoH payload/signature
if (!pohSignature || !pohPayload) {
// Auto-trigger PoH verification
mintStatus.textContent = "Verifying Proof of Humanity...";
const pohResult = await checkPohAndPersist(wallet);
if (!pohResult.status || !pohResult.signature) {
mintStatus.textContent = "PoH verification failed. Cannot mint for free.";
mintStatus.style.color = "#f66";
return;
}
pohSignature = pohResult.signature;
pohPayload = localStorage.getItem(`poh_payload_${wallet.toLowerCase()}`);
if (!pohPayload) {
mintStatus.textContent = "PoH payload missing after verification.";
mintStatus.style.color = "#f66";
// Check if user is PoH verified for free standard tier mint
if (tier === "standard") {
const isPoh = await checkPohStatus(wallet);
if (isPoh) {
// Use mintPoh function for free PoH mint
try {
await mintPoh(wallet, tier, mintStatus);
return; // mintPoh handles the transaction and status updates
} catch (err) {
// Error already handled in mintPoh, just return
return;
}
}
tx = await contract.mintPoHFree(params, pohPayload, pohSignature);
} else if (tier === "standard") {
// Fall through to paid standard mint if not PoH verified
}

// Paid minting paths (standard without PoH, VIP, Premium)
if (tier === "standard") {
tx = await contract.mintStandard(params, { value: priceWei });
} else if (tier === "vip") {
const code = document.getElementById("secretCode").value.trim();
Expand Down
Loading
Loading