Contractless-Web3-Wallets/extension/dist/firefox/popup.html

655 lines
30 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Contractless Wallet</title>
<script type="module" crossorigin src="/popup.js"></script>
<link rel="modulepreload" crossorigin href="/chunks/modulepreload-polyfill-B5Qt9EMX.js">
<link rel="modulepreload" crossorigin href="/chunks/core-D2IK1U91.js">
<link rel="stylesheet" crossorigin href="/assets/popup-B3vY8vDf.css">
</head>
<body>
<main class="wallet-shell">
<section id="loading" class="screen loading-screen">
<div class="loading-brand">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="Contractless" />
<div class="spinner" aria-label="Loading"></div>
</div>
<p>Opening wallet</p>
</section>
<section id="create-screen" class="screen" hidden>
<header class="wallet-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small>Browser Wallet</small></div>
<span>1 of 3</span>
</header>
<div class="screen-content">
<div class="network-choice" role="group" aria-label="Wallet network">
<button type="button" data-select-network="testnet">Testnet</button>
<button type="button" data-select-network="mainnet">Mainnet</button>
</div>
<span class="eyebrow">New wallet</span>
<h1>Create your wallet</h1>
<p class="intro">Choose an encryption key used to unlock and recover this wallet.</p>
<label for="new-password">Encryption key</label>
<div class="input-row">
<input id="new-password" type="password" autocomplete="new-password" />
<button class="reveal" type="button" data-input="new-password">Show</button>
</div>
<div class="note">
<strong>This key is not stored for you.</strong>
<span>You will verify it before the wallet is created.</span>
</div>
<button id="continue-create" class="primary" type="button">Continue <span></span></button>
<div class="divider"><span>or restore an existing wallet</span></div>
<button class="secondary navigation" data-screen="image-screen" type="button">
Import wallet from image
</button>
<button class="secondary navigation" data-screen="private-screen" type="button">
Import wallet from private key
</button>
<button id="cancel-wallet-add" class="text-button" type="button" hidden>
Cancel
</button>
</div>
</section>
<section id="image-screen" class="screen" hidden>
<header class="wallet-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small>Browser Wallet</small></div>
<span data-network-name>Testnet</span>
</header>
<form id="import-image-form" class="screen-content">
<span class="eyebrow">Existing wallet</span>
<h1>Import wallet image</h1>
<p class="intro">
Select your encrypted private-key image and enter the encryption key
originally used to create it.
</p>
<label class="file-heading" for="wallet-image">Wallet image</label>
<label class="file-picker" for="wallet-image">
<span class="file-icon">+</span>
<span><strong id="image-file-name">Choose wallet image</strong><small>PNG encrypted private-key image</small></span>
</label>
<input id="wallet-image" class="visually-hidden" type="file" accept="image/png" />
<label for="image-password">Encryption key</label>
<div class="input-row">
<input id="image-password" type="password" autocomplete="current-password" />
<button class="reveal" type="button" data-input="image-password">Show</button>
</div>
<button id="import-image" class="primary" type="submit">Import wallet</button>
<button class="text-button navigation" data-screen="create-screen" type="button">Back</button>
</form>
</section>
<section id="private-screen" class="screen" hidden>
<header class="wallet-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small>Browser Wallet</small></div>
<span data-network-name>Testnet</span>
</header>
<div class="screen-content compact">
<span class="eyebrow">Existing wallet</span>
<h1>Import private key</h1>
<p class="intro">
Paste the private key, then choose the encryption key that will protect
this wallet from now on.
</p>
<label for="private-key">Private key</label>
<textarea id="private-key" rows="4" placeholder="Paste private key"></textarea>
<label for="private-password">New encryption key</label>
<div class="input-row">
<input id="private-password" type="password" autocomplete="new-password" />
<button class="reveal" type="button" data-input="private-password">Show</button>
</div>
<div class="note compact-note">
<strong>This key protects the new wallet image.</strong>
<span>Store it securely and separately from the image.</span>
</div>
<button id="import-private" class="primary" type="button">Import and create wallet</button>
<button class="text-button navigation" data-screen="create-screen" type="button">Back</button>
</div>
</section>
<section id="verify-screen" class="screen" hidden>
<header class="wallet-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small>Browser Wallet</small></div>
<span>2 of 3</span>
</header>
<div class="screen-content">
<span class="eyebrow">Recovery</span>
<h1>Verify your encryption key</h1>
<p class="intro">
Enter the same key again. Keep it somewhere secure and separate from
your wallet image.
</p>
<label for="verify-password">Re-enter encryption key</label>
<div class="input-row">
<input id="verify-password" type="password" autocomplete="new-password" />
<button class="reveal" type="button" data-input="verify-password">Show</button>
</div>
<div class="warning">
<strong>There is no password reset.</strong>
Losing this key means the wallet image cannot restore your wallet.
</div>
<button id="create-wallet" class="primary" type="button">Create wallet <span></span></button>
<button class="text-button navigation" data-screen="create-screen" type="button">Back</button>
</div>
</section>
<section id="backup-screen" class="screen" hidden>
<header class="wallet-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small>Browser Wallet</small></div>
<span>3 of 3</span>
</header>
<div class="screen-content backup-content">
<span class="success-mark"></span>
<h1>Your wallet is ready</h1>
<p class="intro">
Save the private-key image now. You need both this image and your
encryption key to recover the wallet.
</p>
<div class="image-preview">
<img id="wallet-image-preview" alt="Encrypted private-key wallet image" />
</div>
<button id="save-image" class="primary" type="button">↓ Save wallet image</button>
<label class="confirmation">
<input id="backup-confirmed" type="checkbox" disabled />
<span>I saved the image and stored my encryption key separately.</span>
</label>
<button id="open-wallet" class="secondary" type="button" disabled>Open wallet</button>
</div>
</section>
<section id="locked-screen" class="screen" hidden>
<form id="unlock-form" class="centered-content">
<img class="large-logo" src="/assets/contractless-logo-BgfMS-Kf.png" alt="Contractless" />
<div class="network-choice" role="group" aria-label="Wallet network">
<button type="button" data-select-network="testnet">Testnet</button>
<button type="button" data-select-network="mainnet">Mainnet</button>
</div>
<h1>Unlock wallet</h1>
<p class="intro">Enter your encryption key to continue.</p>
<label for="unlock-password">Encryption key</label>
<div class="input-row">
<input id="unlock-password" type="password" autocomplete="current-password" />
<button class="reveal" type="button" data-input="unlock-password">Show</button>
</div>
<button id="unlock-wallet" class="primary" type="submit">Unlock wallet</button>
</form>
</section>
<section id="provider-approval-screen" class="screen provider-approval-screen" hidden>
<header class="wallet-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small>Wallet request</small></div>
<span>Review</span>
</header>
<div class="screen-content">
<div class="approval-context">
<span class="eyebrow" id="provider-approval-origin"></span>
<span id="provider-approval-risk" class="risk-label"></span>
</div>
<h1 id="provider-approval-title">Review request</h1>
<p class="intro" id="provider-approval-intro">Review this request before approving it.</p>
<dl id="provider-approval-details" class="approval-details"></dl>
</div>
<div class="approval-actions">
<button id="reject-provider-approval" class="secondary" type="button">Reject</button>
<button id="approve-provider-approval" class="primary" type="button">Approve</button>
</div>
</section>
<section id="dashboard-screen" class="screen" hidden>
<header class="wallet-header dashboard-header">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
<div><strong>Contractless</strong><small data-network-name>Testnet</small></div>
<button
id="account-menu-button"
class="account-button"
type="button"
title="Wallets and settings"
aria-expanded="false"
aria-controls="account-drawer"
>
<span class="network-dot"></span>
<span id="wallet-address-short">Account</span>
</button>
</header>
<div class="assets-dashboard">
<nav class="wallet-actions" aria-label="Wallet actions">
<button id="open-send" type="button">
<span class="action-icon"></span>
<span>Send</span>
</button>
<button id="open-receive" type="button">
<span class="action-icon"></span>
<span>Receive</span>
</button>
<button id="open-nfts" type="button">
<span class="action-icon">#</span>
<span>NFTs/RWAs</span>
</button>
<button id="open-activity" type="button">
<span class="action-icon"></span>
<span>Activity</span>
</button>
</nav>
<section class="portfolio-balance" aria-labelledby="portfolio-title">
<span id="portfolio-title">Available balance</span>
<strong><span id="base-balance">0.00000000</span> <small data-network-symbol>CLTC</small></strong>
<p id="wallet-address"></p>
</section>
<section class="asset-ledger" aria-labelledby="assets-title">
<div class="asset-ledger-heading">
<h1 id="assets-title">Assets</h1>
<button id="refresh-balances" type="button" title="Refresh balances" aria-label="Refresh balances"></button>
</div>
<div class="asset-filter" role="group" aria-label="Token visibility">
<button class="active" data-token-filter="held" type="button">Held tokens</button>
<button data-token-filter="all" type="button">All tokens</button>
</div>
<div class="asset-row base-asset">
<div class="asset-symbol contractless-symbol">
<img src="/assets/contractless-logo-BgfMS-Kf.png" alt="" />
</div>
<div class="asset-name">
<strong id="base-asset-name">Contractless Testnet</strong>
<span data-network-symbol>CLTC</span>
</div>
<div class="asset-value">
<strong id="base-asset-balance">0.00000000</strong>
<span data-network-symbol>CLTC</span>
</div>
</div>
<div id="token-list" class="token-list">
<div class="empty-assets">
<strong>Loading token balances...</strong>
<span>Balances are retrieved from the selected Contractless API.</span>
</div>
</div>
</section>
</div>
</section>
<section id="nfts-screen" class="screen nfts-screen" hidden>
<header class="wallet-header">
<button id="close-nfts" class="header-back" type="button" title="Back to assets" aria-label="Back to assets">&larr;</button>
<div><strong>NFTs and RWAs</strong><small>Assets owned by this wallet</small></div>
<button id="refresh-nfts" class="header-refresh" type="button" title="Refresh assets" aria-label="Refresh assets">&#8635;</button>
</header>
<div class="nfts-content">
<div class="nfts-summary">
<span id="nfts-count">Loading ownership...</span>
<span data-network-name>Testnet</span>
</div>
<div id="nfts-list" class="nfts-list"></div>
<div id="nfts-pagination" class="nfts-pagination" hidden>
<button id="nfts-previous" type="button" aria-label="Previous NFT page">&larr;</button>
<span>Page <strong id="nfts-page">1</strong> of <strong id="nfts-pages">1</strong></span>
<button id="nfts-next" type="button" aria-label="Next NFT page">&rarr;</button>
</div>
</div>
</section>
<section id="nft-detail-screen" class="screen nft-detail-screen" hidden>
<header class="wallet-header">
<button id="close-nft-detail" class="header-back" type="button" title="Back to NFTs and RWAs" aria-label="Back to NFTs and RWAs">&larr;</button>
<div><strong id="nft-detail-title">NFT/RWA</strong><small id="nft-detail-kind">On-chain asset</small></div>
<span data-network-name>Testnet</span>
</header>
<div class="nft-detail-content">
<div class="nft-detail-media">
<img id="nft-detail-image" alt="" />
</div>
<div class="nft-detail-heading">
<div>
<span id="nft-detail-badge">NFT</span>
<h1 id="nft-detail-name">NFT/RWA</h1>
</div>
<strong id="nft-detail-ownership"></strong>
</div>
<p id="nft-detail-description" class="nft-detail-description"></p>
<div id="nft-detail-attributes" class="nft-detail-attributes"></div>
<dl id="nft-detail-fields" class="nft-detail-fields"></dl>
<div class="nft-detail-actions">
<button id="transfer-nft" class="primary" type="button">Transfer asset</button>
</div>
<section class="nft-provenance">
<h2>Provenance</h2>
<div id="nft-detail-history"></div>
</section>
</div>
</section>
<section id="send-screen" class="screen send-screen" hidden>
<header class="wallet-header">
<button id="close-send" class="header-back" type="button" title="Back to assets" aria-label="Back to assets"></button>
<div><strong>Send</strong><small>Create a transfer</small></div>
<span data-network-name>Testnet</span>
</header>
<form id="send-form" class="send-content">
<div>
<label for="send-asset">Asset</label>
<select id="send-asset"></select>
</div>
<div>
<label for="send-recipient">Receiving address</label>
<input id="send-recipient" type="text" autocomplete="off" spellcheck="false" placeholder="Wallet or vanity address" />
</div>
<div>
<label for="send-amount">Amount</label>
<div class="send-amount-row">
<input id="send-amount" type="text" inputmode="decimal" autocomplete="off" placeholder="0.00000000" />
<span id="send-amount-symbol" data-network-symbol>CLTC</span>
</div>
<span id="send-available" class="field-note">Available: 0.00000000 CLTC</span>
</div>
<div>
<label for="send-fee">Transaction fee</label>
<div class="send-amount-row">
<input id="send-fee" type="text" inputmode="decimal" autocomplete="off" placeholder="0.00000000" />
<span data-network-symbol>CLTC</span>
</div>
<span id="send-fee-note" class="field-note">Minimum fee: 1% of the transfer amount.</span>
</div>
<button class="primary send-continue" type="submit">Review transfer</button>
</form>
</section>
<section id="send-review-screen" class="screen send-review-screen" hidden>
<header class="wallet-header">
<button id="edit-send" class="header-back" type="button" title="Edit transfer" aria-label="Edit transfer"></button>
<div><strong>Review transfer</strong><small>Confirm before signing</small></div>
<span data-network-name>Testnet</span>
</header>
<div class="send-review-content">
<div class="send-review-amount">
<span>You are sending</span>
<strong><span id="review-amount">0.00000000</span> <small id="review-asset">CLTC</small></strong>
</div>
<dl class="send-review-details">
<div><dt>From</dt><dd id="review-sender"></dd></div>
<div><dt>To</dt><dd id="review-recipient"></dd></div>
<div><dt>Resolved address</dt><dd id="review-resolved-recipient"></dd></div>
<div><dt>Transaction fee</dt><dd><span id="review-fee"></span> <span data-network-symbol>CLTC</span></dd></div>
<div><dt>Total deducted</dt><dd id="review-total"></dd></div>
</dl>
<p class="signing-notice">Your private key remains inside this wallet. The transaction is signed locally and only the completed transaction is sent to the API.</p>
<button id="sign-broadcast-transfer" class="primary" type="button">Sign and broadcast</button>
</div>
</section>
<section id="send-success-screen" class="screen send-success-screen" hidden>
<header class="wallet-header">
<div><strong>Transfer broadcast</strong><small>Submitted to Contractless</small></div>
<span data-network-name>Testnet</span>
</header>
<div class="send-success-content">
<span class="success-mark"></span>
<h1>Transaction sent</h1>
<p>The signed transfer was accepted for broadcast.</p>
<div class="send-txid">
<span>Transaction ID</span>
<strong id="send-result-txid"></strong>
</div>
<button id="copy-send-txid" class="secondary" type="button">Copy transaction ID</button>
<button id="finish-send" class="primary" type="button">Return to assets</button>
</div>
</section>
<section id="activity-screen" class="screen activity-screen" hidden>
<header class="wallet-header">
<button id="close-activity" class="header-back" type="button" title="Back to assets" aria-label="Back to assets"></button>
<div><strong>Activity</strong><small>Latest 25 transactions</small></div>
<span data-network-name>Testnet</span>
</header>
<div class="activity-content">
<div class="activity-summary">
<span>Newest transactions first</span>
<div>
<strong id="activity-count">0 shown</strong>
<button id="refresh-activity" type="button" title="Refresh activity" aria-label="Refresh activity"></button>
</div>
</div>
<div id="activity-list" class="activity-list"></div>
</div>
</section>
<section id="transaction-screen" class="screen transaction-screen" hidden>
<header class="wallet-header">
<button id="close-transaction" class="header-back" type="button" title="Back to activity" aria-label="Back to activity"></button>
<div><strong id="transaction-title">Transaction</strong><small>Complete on-chain details</small></div>
<span id="transaction-header-status"></span>
</header>
<div class="transaction-content">
<section class="transaction-identity">
<div>
<span>Transaction ID</span>
<strong id="transaction-full-txid"></strong>
</div>
<button id="copy-transaction-txid" type="button">Copy TXID</button>
</section>
<div id="transaction-overview" class="transaction-fields"></div>
<section class="transaction-section">
<h2>Transaction Fields</h2>
<div id="transaction-fields" class="transaction-fields"></div>
</section>
<section id="miner-earnings-section" class="transaction-section" hidden>
<h2>Miner Earnings</h2>
<div id="transaction-miner-earnings" class="transaction-fields"></div>
</section>
<details class="transaction-technical">
<summary>Technical Details</summary>
<div id="transaction-technical-fields" class="transaction-fields"></div>
</details>
</div>
</section>
<section id="receive-screen" class="screen receive-screen" hidden>
<header class="wallet-header">
<button id="close-receive" class="header-back" type="button" title="Back to assets" aria-label="Back to assets"></button>
<div><strong>Receive</strong><small>Contractless wallet address</small></div>
<span data-network-name>Testnet</span>
</header>
<div class="receive-content">
<span class="receive-label">Receive <span data-network-symbol>CLTC</span> and Contractless assets</span>
<h1>Share your address</h1>
<p>
Scan the QR code or copy the address below. Only send assets issued on
the Contractless <span data-network-name>Testnet</span> network to this address.
</p>
<div class="qr-frame">
<canvas id="receive-qr" width="220" height="220" aria-label="Wallet address QR code"></canvas>
</div>
<div class="receive-address">
<span id="receive-address-label">Wallet address</span>
<strong id="receive-address-value"></strong>
</div>
<button id="copy-receive-address" class="primary receive-copy" type="button">
Copy address
</button>
</div>
</section>
<div id="drawer-backdrop" class="drawer-backdrop" hidden></div>
<aside id="account-drawer" class="account-drawer" aria-hidden="true">
<header class="drawer-header">
<div>
<strong>Wallets</strong>
<span>Accounts and settings</span>
</div>
<button id="close-account-drawer" type="button" title="Close menu" aria-label="Close menu">×</button>
</header>
<section class="drawer-section">
<span class="drawer-label">Network</span>
<div class="network-choice drawer-network" role="group" aria-label="Wallet network">
<button type="button" data-select-network="testnet">Testnet</button>
<button type="button" data-select-network="mainnet">Mainnet</button>
</div>
</section>
<section class="drawer-section">
<span class="drawer-label">Known addresses</span>
<div id="known-addresses" class="known-addresses"></div>
</section>
<nav class="drawer-navigation" aria-label="Wallet menu">
<button id="menu-create-wallet" type="button">
<span class="menu-icon">+</span>
<span><strong>Create another address</strong><small>Generate a new Contractless wallet</small></span>
<span class="menu-arrow"></span>
</button>
<button id="menu-import-wallet" type="button">
<span class="menu-icon"></span>
<span><strong>Import another address</strong><small>Use an image or private key</small></span>
<span class="menu-arrow"></span>
</button>
<button id="menu-settings" type="button">
<span class="menu-icon"></span>
<span><strong>Settings</strong><small>API endpoint and lock timeout</small></span>
<span class="menu-arrow"></span>
</button>
</nav>
<button id="drawer-lock-wallet" class="drawer-lock" type="button">
<span></span>
Lock wallet
</button>
</aside>
<section id="settings-screen" class="screen settings-screen" hidden>
<header class="wallet-header">
<button id="close-settings" class="header-back" type="button" title="Back to assets" aria-label="Back to assets"></button>
<div><strong>Settings</strong><small>Wallet preferences and backup</small></div>
</header>
<div class="settings-content">
<section class="settings-group">
<div class="settings-heading">
<strong>Security</strong>
<span>Control how long the active wallet stays unlocked.</span>
</div>
<label for="settings-lock-timeout">Automatic lock</label>
<select id="settings-lock-timeout">
<option value="15">15 minutes</option>
<option value="30">30 minutes</option>
<option value="60">60 minutes</option>
<option value="240">4 hours</option>
<option value="720">12 hours</option>
<option value="1440">24 hours</option>
</select>
</section>
<section class="settings-group">
<div class="settings-heading">
<strong>Contractless API</strong>
<span>Choose the API used for lookups and transaction broadcasts.</span>
</div>
<label for="settings-testnet-api-url">Testnet API URL</label>
<input id="settings-testnet-api-url" type="url" value="https://api.contractless.dev" />
<label for="settings-mainnet-api-url">Mainnet API URL</label>
<input id="settings-mainnet-api-url" type="url" placeholder="Not configured" />
<span class="settings-help">Mainnet wallets can be created and backed up before a mainnet API is configured.</span>
</section>
<button id="save-wallet-settings" class="primary settings-save" type="button">Save settings</button>
<section class="settings-group backup-settings">
<div class="settings-heading">
<strong>Active wallet backup</strong>
<span>These actions require the active wallet encryption key.</span>
</div>
<button class="settings-action" data-backup-action="image" type="button">
<span class="settings-action-icon"></span>
<span><strong>Save wallet image</strong><small>Download an encrypted PNG backup</small></span>
<span></span>
</button>
<button class="settings-action" data-backup-action="private" type="button">
<span class="settings-action-icon"></span>
<span><strong>View private key</strong><small>Reveal and copy the active private key</small></span>
<span></span>
</button>
<button class="settings-action" data-backup-action="print" type="button">
<span class="settings-action-icon"></span>
<span><strong>Print wallet backup</strong><small>Private key and encryption key</small></span>
<span></span>
</button>
</section>
<section id="private-key-result" class="private-key-result" hidden>
<div>
<strong>Private key</strong>
<button id="clear-private-key" type="button" title="Clear private key" aria-label="Clear private key">×</button>
</div>
<textarea id="revealed-private-key" readonly></textarea>
<button id="copy-private-key" class="secondary" type="button">Copy private key</button>
</section>
</div>
</section>
<div id="backup-key-backdrop" class="modal-backdrop" hidden></div>
<section id="backup-key-modal" class="backup-key-modal" hidden aria-modal="true" role="dialog" aria-labelledby="backup-key-title">
<header>
<div>
<strong id="backup-key-title">Confirm encryption key</strong>
<span>Required to decrypt this wallet locally.</span>
</div>
<button id="close-backup-key" type="button" title="Cancel" aria-label="Cancel">×</button>
</header>
<div>
<label for="backup-key-input">Encryption key</label>
<div class="input-row">
<input id="backup-key-input" type="password" autocomplete="current-password" />
<button class="reveal" type="button" data-input="backup-key-input">Show</button>
</div>
<button id="confirm-backup-key" class="primary" type="button">Continue</button>
</div>
</section>
<p id="notice" role="alert" aria-live="polite"></p>
</main>
</body>
</html>