Rust implementation of NextGraph, a Decentralized and local-first web 3.0 ecosystem https://nextgraph.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nextgraph-rs/ng-app/src/routes/WalletCreate.svelte

1757 lines
73 KiB

2 years ago
<!--
1 year ago
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
2 years ago
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
-->
<!--
@component
Wallet creation page.
This component manages the whole UX flow, gives infos about wallets,
offers available brokers, handles wallet creation,
and shows the wallet pazzle and pin.
-->
<script lang="ts">
9 months ago
import { Button, Alert, Dropzone, Toggle, Modal } from "flowbite-svelte";
2 years ago
import { link, querystring } from "svelte-spa-router";
import { t } from "svelte-i18n";
import CenteredLayout from "../lib/CenteredLayout.svelte";
9 months ago
import CopyToClipboard from "../lib/components/CopyToClipboard.svelte";
2 years ago
// @ts-ignore
2 years ago
import EULogo from "../assets/EU.svg?component";
2 years ago
// @ts-ignore
2 years ago
import Logo from "../assets/nextgraph.svg?component";
2 years ago
import {
NG_EU_BSP,
NG_NET_BSP,
LINK_NG_BOX,
LINK_SELF_HOST,
2 years ago
NG_EU_BSP_REGISTER,
NG_NET_BSP_REGISTER,
APP_WALLET_CREATE_SUFFIX,
2 years ago
default as ng,
} from "../api";
9 months ago
import {
display_pazzle,
emojis_from_pazzle_ids,
load_svg,
} from "../wallet_emojis";
2 years ago
import { onMount, onDestroy, tick } from "svelte";
2 years ago
import { wallets, set_active_session, has_wallets } from "../store";
import Spinner from "../lib/components/Spinner.svelte";
2 years ago
2 years ago
const param = new URLSearchParams($querystring);
2 years ago
let tauri_platform = import.meta.env.TAURI_PLATFORM;
let mobile = tauri_platform == "android" || tauri_platform == "ios";
9 months ago
let is_touch_device =
"ontouchstart" in window ||
navigator.maxTouchPoints > 0 ||
// @ts-ignore
navigator?.msMaxTouchPoints > 0;
2 years ago
const onFileSelected = (image) => {
animate_bounce = false;
if (!security_txt) phrase.focus();
let reader = new FileReader();
reader.readAsArrayBuffer(image);
reader.onload = async (e) => {
security_img = e.target.result;
//console.log(security_img);
2 years ago
var blob = new Blob([security_img], {
type: image.type,
});
image_url = URL.createObjectURL(blob);
phrase.scrollIntoView();
if (security_txt) {
await tick();
validate_button.focus();
}
};
};
const security_phrase_ok = async (e) => {
if (!e || e.key == "Enter" || e.keyCode == 13) {
phrase.blur();
if (!security_img) {
animate_bounce = true;
img_preview.scrollIntoView();
} else {
await tick();
validate_button.scrollIntoView();
validate_button.focus();
}
}
};
const dropHandle = (event) => {
event.preventDefault();
const files = event.dataTransfer.files;
if (files.length > 0) {
onFileSelected(files[0]);
}
};
const handleChange = (event) => {
const files = event.target.files;
if (files.length > 0) {
onFileSelected(files[0]);
}
};
let intro = true;
let wait: any = false;
let registration_error;
let registration_success;
2 years ago
let pin = [];
let pin_confirm = [];
let security_txt = "";
let security_img;
let top;
let img_preview;
let phrase;
let validate_button;
let animate_bounce;
let image_url =
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
2 years ago
let info_options;
let options;
let creating = false;
let error;
let ready;
let download_link;
let download_name;
let cloud_link;
let animateDownload = true;
2 years ago
let invitation;
let pre_invitation;
2 years ago
let unsub_register_accepted;
let unsub_register_error;
let unsub_register_close;
9 months ago
/** The emojis for the newly created pazzle. */
let pazzle_emojis = [];
let confirm_modal_open = false;
let device_name;
2 years ago
function scrollToTop() {
top.scrollIntoView();
}
function sel_pin(val) {
if (pin.length < 4) {
pin.push(val);
pin = pin;
}
}
async function confirm_pin(val) {
2 years ago
if (pin_confirm.length < 4) {
pin_confirm.push(val);
pin_confirm = pin_confirm;
if (pin_confirm.length == 4) {
await tick();
scrollToTop();
}
2 years ago
}
}
const api_url = import.meta.env.PROD
? "api/v1/"
: "http://localhost:3030/api/v1/";
async function bootstrap() {
//console.log(await ng.client_info());
if (!tauri_platform || tauri_platform == "android") {
if (param.get("skipintro") || param.get("rs")) {
intro = false;
}
if (param.get("re")) {
registration_error = param.get("re");
}
if (param.get("rs")) {
registration_success = param.get("rs");
invitation = await ng.decode_invitation(param.get("i"));
window.location.replace(window.location.href.split("?")[0]);
} else if (param.get("i")) {
invitation = await ng.get_local_bootstrap_with_public(
location.href,
param.get("i")
);
console.log("invitation", invitation);
if (invitation && invitation.V0.url) {
pre_invitation = invitation;
invitation = undefined;
} else if (!invitation) {
let redirect = await ng.get_ngone_url_of_invitation(param.get("i"));
if (redirect) {
console.error("got an invitation for another broker. redirecting");
window.location.href = redirect;
} else {
//let i = await ng.decode_invitation(param.get("i"));
console.error("invalid invitation. ignoring it");
}
}
} else {
pre_invitation = await ng.get_local_bootstrap_with_public(
location.href
);
console.log("pre_invitation", pre_invitation);
}
2 years ago
}
2 years ago
scrollToTop();
9 months ago
// We need them for display later.
load_svg();
2 years ago
}
function create_wallet() {
intro = false;
// if (invitation && invitation.V0.url) {
// // we redirect to the TOS url of the invitation.
// wait = "Redirecting to TOS";
// window.location.href = invitation.V0.url;
// }
2 years ago
scrollToTop();
}
async function save_security() {
8 months ago
device_name = await ng.get_device_name();
2 years ago
options = {
trusted: true,
cloud: false,
bootstrap: false,
pdf: false,
2 years ago
};
await tick();
scrollToTop();
2 years ago
}
async function do_wallet() {
creating = true;
let local_invitation = await ng.get_local_bootstrap(location.href);
let additional_bootstrap;
if (local_invitation) {
additional_bootstrap = local_invitation.V0.bootstrap;
}
let core_registration;
if (invitation.V0.code) {
core_registration = invitation.V0.code.ChaCha20Key;
}
2 years ago
let params = {
security_img: security_img,
security_txt,
pin,
pazzle_length: 9,
2 years ago
send_bootstrap: false, //options.cloud || options.bootstrap ? : undefined,
2 years ago
send_wallet: options.cloud,
local_save: options.trusted,
2 years ago
result_with_wallet_file: false, // this will be automatically changed to true for browser app
core_bootstrap: invitation.V0.bootstrap,
core_registration,
additional_bootstrap,
8 months ago
//TODO: device_name,
2 years ago
};
//console.log("do wallet with params", params);
2 years ago
try {
ready = await ng.wallet_create(params);
wallets.set(await ng.get_wallets());
if (!options.trusted && !tauri_platform) {
let lws = $wallets[ready.wallet_name];
if (lws.in_memory) {
let new_in_mem = {
lws,
name: ready.wallet_name,
opened: false,
cmd: "new_in_mem",
};
window.wallet_channel.postMessage(new_in_mem, location.href);
}
}
9 months ago
console.log("pazzle", ready.pazzle);
console.log("pazzle words", display_pazzle(ready.pazzle));
console.log("mnemonic", ready.mnemonic);
console.log("mnemonic words", ready.mnemonic_str);
2 years ago
download_name = "wallet-" + ready.wallet_name + ".ngw";
2 years ago
if (options.cloud) {
cloud_link = "https://nextgraph.one/#/w/" + ready.wallet_name;
2 years ago
}
2 years ago
if (ready.wallet_file.length) {
const blob = new Blob([ready.wallet_file], {
type: "application/octet-stream",
});
2 years ago
download_link = URL.createObjectURL(blob);
}
} catch (e) {
console.error(e);
2 years ago
error = e;
}
}
// async function getWallet() {
// const opts = {
// method: "get",
// };
// const response = await fetch(
// api_url + "bootstrap/I8tuoVE-LRH1wuWQpDBPivlSX8Wle39uHSL576BTxsk",
// opts
// );
// const result = await response.json();
// console.log("Result:", result);
// }
2 years ago
2 years ago
onMount(async () => await bootstrap());
2 years ago
ready = false;
2 years ago
const unsub_register = () => {
if (unsub_register_accepted) unsub_register_accepted();
if (unsub_register_error) unsub_register_error();
if (unsub_register_close) unsub_register_close();
unsub_register_close = undefined;
unsub_register_error = undefined;
unsub_register_accepted = undefined;
};
onDestroy(() => {
unsub_register();
});
const select_bsp = async (bsp_url, bsp_name) => {
if (!tauri_platform || tauri_platform == "android") {
let redirect_url;
if (tauri_platform) {
redirect_url = window.location.href;
} else {
let local_url;
if (!import.meta.env.PROD) {
local_url = "http://localhost:1421";
} else {
local_url = await ng.get_local_url(location.href);
}
if (local_url) redirect_url = local_url + APP_WALLET_CREATE_SUFFIX;
}
2 years ago
let create = {
V0: {
redirect_url,
2 years ago
},
};
let ca = await ng.encode_create_account(create);
wait = $t("pages.wallet_create.redirecting_to_registration_page");
window.location.href = bsp_url + "?ca=" + ca;
2 years ago
//window.open(), "_self").focus();
} else {
let create = {
V0: {
2 years ago
redirect_url: undefined,
2 years ago
},
};
wait = $t("pages.wallet_create.complete_in_popup");
2 years ago
let ca = await ng.encode_create_account(create);
await ng.open_window(
bsp_url + "?ca=" + ca,
"registration",
"Registration at a Broker"
);
let window_api = await import("@tauri-apps/plugin-window");
let event_api = await import("@tauri-apps/api/event");
unsub_register_accepted = await event_api.listen(
"accepted",
async (event) => {
wait = false;
console.log("got accepted with payload", event.payload);
unsub_register();
let reg_popup = window_api.Window.getByLabel("registration");
await reg_popup.close();
registration_success = bsp_name;
invitation = await ng.decode_invitation(event.payload.invite);
}
);
unsub_register_error = await event_api.listen("error", async (event) => {
wait = false;
console.log("got error with payload", event.payload);
if (event.payload) registration_error = event.payload.error;
else intro = true;
unsub_register();
let reg_popup = window_api.Window.getByLabel("registration");
await reg_popup.close();
});
await tick();
await new Promise((resolve) => setTimeout(resolve, 1000));
let reg_popup = window_api.Window.getByLabel("registration");
unsub_register_close = await reg_popup.onCloseRequested(async (event) => {
console.log("onCloseRequested");
wait = false;
intro = true;
unsub_register_close = undefined;
unsub_register();
});
2 years ago
}
};
const selectEU = async (event) => {
await select_bsp(NG_EU_BSP_REGISTER, "nextgraph.eu");
};
const selectNET = async (event) => {
await select_bsp(NG_NET_BSP_REGISTER, "nextgraph.net");
};
2 years ago
const enterINVITE = (event) => {};
const enterQRcode = (event) => {};
const displayPopup = async (url, title) => {
if (!tauri_platform || tauri_platform == "android") {
window.open(url, "_blank").focus();
} else {
await ng.open_window(url, "viewer", title);
}
};
const displayNGbox = async (event) => {
await displayPopup(LINK_NG_BOX, $t("pages.wallet_create.own_your_ngbox"));
};
const displaySelfHost = async (event) => {
await displayPopup(
LINK_SELF_HOST,
$t("pages.wallet_create.self_host_broker")
);
};
const tos = async () => {
await displayPopup(
"https://nextgraph.one/#/tos",
$t("pages.wallet_create.tos_ng_one")
);
};
9 months ago
const load_pazzle_emojis = async (pazzle_ids: number[]) => {
// We wait until the SVGs are available. If they are already, we return immediately.
await load_svg();
pazzle_emojis = emojis_from_pazzle_ids(pazzle_ids);
};
$: if (ready?.pazzle) {
load_pazzle_emojis(ready.pazzle);
}
// Loads an example wallet.
// const loadWallet = async () => {
// options = {
// trusted: true,
// cloud: false,
// bootstrap: false,
// pdf: false,
// };
// creating = true;
// let local_invitation = await ng.get_local_bootstrap(location.href);
// let additional_bootstrap;
// if (local_invitation) {
// additional_bootstrap = local_invitation.V0.bootstrap;
// }
// let core_registration;
// if (invitation?.V0.code) {
// core_registration = invitation.V0.code.ChaCha20Key;
// }
// let params = {
// security_img: security_img,
// security_txt,
// pin,
// pazzle_length: 9,
// send_bootstrap: false, //options.cloud || options.bootstrap ? : undefined,
// send_wallet: options.cloud,
// local_save: options.trusted,
// result_with_wallet_file: false, // this will be automatically changed to true for browser app
// core_bootstrap: invitation?.V0.bootstrap,
// core_registration,
// additional_bootstrap,
// };
// try {
// ready = await import("./wallet.json");
// wallets.set(await ng.get_wallets());
// if (!options.trusted && !tauri_platform) {
// let lws = $wallets[ready.wallet_name];
// if (lws.in_memory) {
// let new_in_mem = {
// lws,
// name: ready.wallet_name,
// opened: false,
// cmd: "new_in_mem",
// };
// window.wallet_channel.postMessage(new_in_mem, location.href);
// }
// }
// console.log("pazzle ids", ready.pazzle);
// console.log("pazzle emojis", emojis_from_pazzle_ids(ready.pazzle));
// download_name = "wallet-" + ready.wallet_name + ".ngw";
// if (options.cloud) {
// cloud_link = "https://nextgraph.one/#/w/" + ready.wallet_name;
// }
// if (ready.wallet_file.length) {
// const blob = new Blob([ready.wallet_file], {
// type: "application/octet-stream",
// });
// download_link = URL.createObjectURL(blob);
// }
// } catch (e) {
// console.error(e);
// error = e;
// }
// wait = false;
// registration_error = false;
// intro = false;
// pin = [0, 8, 1, 5];
// pin_confirm = [0, 8, 1, 5];
// invitation = true;
// };
// loadWallet();
9 months ago
let width: number;
let height: number;
const breakPointWidth: number = 450;
const breakPointHeight: number = 500;
let small_screen = false;
$: if (width >= breakPointWidth && height >= breakPointHeight) {
small_screen = false;
} else {
small_screen = true;
}
2 years ago
</script>
9 months ago
<svelte:window bind:innerWidth={width} bind:innerHeight={height} />
<CenteredLayout>
9 months ago
<div class="max-w-2xl lg:px-8 mx-auto">
9 months ago
{#if wait}
<div class="lg:px-8 text-primary-700">
{#if wait === true}
{$t("pages.wallet_create.please_wait")}...
9 months ago
{:else}
{wait}
{/if}
<Spinner className="mt-10 h-14 w-14 mx-auto" />
9 months ago
</div>
{:else}
<div class="container3" bind:this={top}>
<div class="row">
<a href="#/">
<Logo class="logo block h-[8em]" alt={$t("common.logo")} />
9 months ago
</a>
</div>
9 months ago
{#if registration_error}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
<svg
9 months ago
class="animate-bounce mt-10 h-16 w-16 mx-auto"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
9 months ago
{#if registration_error == "AlreadyExists"}
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("pages.user_registered.already_exists")}
9 months ago
</p>
<a use:link href="/wallet/login">
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("buttons.login")}
9 months ago
</button>
</a>
{:else}
<p class="max-w-xl md:mx-auto lg:max-w-2xl mb-5">
{@html $t("errors.error_occurred", {
values: { message: $t("errors." + registration_error) },
})}
9 months ago
</p>
<a use:link href="/">
<button
tabindex="-1"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
{$t("bottons.back_to_homepage")}
9 months ago
</button>
</a>
{/if}
</div>
{:else if intro}
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
9 months ago
<p class="max-w-xl text-left md:mx-auto lg:max-w-2xl">
{@html $t("pages.wallet_create.wallet_description")}
9 months ago
</p>
</div>
{#if $has_wallets}
<Alert color="yellow" class="mt-5">
{@html $t("pages.wallet_create.has_wallet")}
9 months ago
</Alert>
{/if}
<div
class="px-4 pt-5 mx-auto max-w-6xl lg:px-8 lg:pt-10 dark:bg-slate-800"
>
<div class="max-w-xl md:mx-auto sm:text-center lg:max-w-2xl">
<h2 class="pb-5 text-xl">
{$t("pages.wallet_create.wallet_about.title")}<span
class="text-sm"
>&nbsp
{$t("pages.wallet_create.wallet_about.please_read")}</span
>
9 months ago
</h2>
<ul
class="mb-8 space-y-4 text-left text-gray-500 dark:text-gray-400"
>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
stroke="currentColor"
fill="none"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.5 10.5V6.75a4.5 4.5 0 10-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 002.25-2.25v-6.75a2.25 2.25 0 00-2.25-2.25H6.75a2.25 2.25 0 00-2.25 2.25v6.75a2.25 2.25 0 002.25 2.25z"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.1")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.2")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M14.25 6.087c0-.355.186-.676.401-.959.221-.29.349-.634.349-1.003 0-1.036-1.007-1.875-2.25-1.875s-2.25.84-2.25 1.875c0 .369.128.713.349 1.003.215.283.401.604.401.959v0a.64.64 0 01-.657.643 48.39 48.39 0 01-4.163-.3c.186 1.613.293 3.25.315 4.907a.656.656 0 01-.658.663v0c-.355 0-.676-.186-.959-.401a1.647 1.647 0 00-1.003-.349c-1.036 0-1.875 1.007-1.875 2.25s.84 2.25 1.875 2.25c.369 0 .713-.128 1.003-.349.283-.215.604-.401.959-.401v0c.31 0 .555.26.532.57a48.039 48.039 0 01-.642 5.056c1.518.19 3.058.309 4.616.354a.64.64 0 00.657-.643v0c0-.355-.186-.676-.401-.959a1.647 1.647 0 01-.349-1.003c0-1.035 1.008-1.875 2.25-1.875 1.243 0 2.25.84 2.25 1.875 0 .369-.128.713-.349 1.003-.215.283-.4.604-.4.959v0c0 .333.277.599.61.58a48.1 48.1 0 005.427-.63 48.05 48.05 0 00.582-4.717.532.532 0 00-.533-.57v0c-.355 0-.676.186-.959.401-.29.221-.634.349-1.003.349-1.035 0-1.875-1.007-1.875-2.25s.84-2.25 1.875-2.25c.37 0 .713.128 1.003.349.283.215.604.401.96.401v0a.656.656 0 00.658-.663 48.422 48.422 0 00-.37-5.36c-1.886.342-3.81.574-5.766.689a.578.578 0 01-.61-.58v0z"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.3")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9 12.75L11.25 15 15 9.75m-3-7.036A11.959 11.959 0 013.598 6 11.99 11.99 0 003 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285z"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.4")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
d="M16.5 12a4.5 4.5 0 11-9 0 4.5 4.5 0 019 0zm0 0c0 1.657 1.007 3 2.25 3S21 13.657 21 12a9 9 0 10-2.636 6.364M16.5 12V8.25"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.5")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15M12 9l-3 3m0 0l3 3m-3-3h12.75"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.6")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.7")}</span>
9 months ago
</li>
<li class="flex space-x-3 under">
<!-- Icon -->
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 18v-5.25m0 0a6.01 6.01 0 001.5-.189m-1.5.189a6.01 6.01 0 01-1.5-.189m3.75 7.478a12.06 12.06 0 01-4.5 0m3.75 2.383a14.406 14.406 0 01-3 0M14.25 18v-.192c0-.983.658-1.823 1.508-2.316a7.5 7.5 0 10-7.517 0c.85.493 1.509 1.333 1.509 2.316V18"
/>
</svg>
<span>{@html $t("pages.wallet_create.wallet_about.8")}</span>
9 months ago
</li>
</ul>
</div>
</div>
<div class="row mb-20">
<button
on:click|once={create_wallet}
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19 7.5v3m0 0v3m0-3h3m-3 0h-3m-2.25-4.125a3.375 3.375 0 11-6.75 0 3.375 3.375 0 016.75 0zM4 19.235v-.11a6.375 6.375 0 0112.75 0v.109A12.318 12.318 0 0110.374 21c-2.331 0-4.512-.645-6.374-1.766z"
/>
</svg>
{@html $t("pages.wallet_create.create_wallet_now")}
9 months ago
</button>
</div>
{:else if !invitation}
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
9 months ago
<p class="max-w-xl md:mx-auto text-left lg:max-w-2xl">
{@html $t("pages.wallet_create.select_server")}
9 months ago
</p>
</div>
<div
class="px-4 pt-3 mx-auto max-w-6xl lg:px-8 lg:pt-10 dark:bg-slate-800"
>
<div class="max-w-xl md:mx-auto sm:text-center lg:max-w-2xl">
<h2 class="pb-5 text-xl">
{$t("pages.wallet_create.broker_about.title")}<span
class="text-sm"
>&nbsp{@html $t(
"pages.wallet_create.broker_about.please_read"
)}</span
>
9 months ago
</h2>
<ul
class="mb-8 space-y-4 text-left text-gray-500 dark:text-gray-400"
>
<li class="flex space-x-3">
<svg
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.1")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 5.25a3 3 0 013 3m3 0a6 6 0 01-7.029 5.912c-.563-.097-1.159.026-1.563.43L10.5 17.25H8.25v2.25H6v2.25H2.25v-2.818c0-.597.237-1.17.659-1.591l6.499-6.499c.404-.404.527-1 .43-1.563A6 6 0 1121.75 8.25z"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.2")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.3")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.4")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M7.5 21L3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.5")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M2.25 12l8.954-8.955c.44-.439 1.152-.439 1.591 0L21.75 12M4.5 9.75v10.125c0 .621.504 1.125 1.125 1.125H9.75v-4.875c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125V21h4.125c.621 0 1.125-.504 1.125-1.125V9.75M8.25 21h8.25"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.6")}</span>
9 months ago
</li>
<li class="flex space-x-3">
<svg
class="flex-shrink-0 w-5 h-5 text-green-500 dark:text-green-400"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M5.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7m0 0a3 3 0 01-3 3m0 3h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008zm-3 6h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008z"
/>
</svg>
<span> {@html $t("pages.wallet_create.broker_about.7")}</span>
9 months ago
</li>
</ul>
<h2 class="mt-3 text-xl">
{$t("pages.wallet_create.choose_broker")}
9 months ago
</h2>
</div>
</div>
{#if pre_invitation}
<div class="row mt-5">
<button
on:click|once={async () => {
await select_bsp(
pre_invitation.V0.url,
pre_invitation.V0.name
);
}}
class="choice-button text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
9 months ago
class="mr-4 block h-10 w-10"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418"
/>
</svg>
{$t("pages.wallet_create.register_with", {
values: { broker: pre_invitation.V0.name || "this broker" },
})}
9 months ago
</button>
</div>
{:else}
<div class="row mt-5">
<button
on:click|once={selectEU}
class="choice-button text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<EULogo
class="mr-4 block h-10 w-10"
alt="European Union flag"
/>
{$t("pages.wallet_create.for_eu_citizens")}
9 months ago
</button>
</div>
9 months ago
<div class="row mt-5">
<button
on:click|once={selectNET}
class="choice-button text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
9 months ago
class="mr-4 block h-10 w-10"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M12 21a9.004 9.004 0 008.716-6.747M12 21a9.004 9.004 0 01-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 017.843 4.582M12 3a8.997 8.997 0 00-7.843 4.582m15.686 0A11.953 11.953 0 0112 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0121 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0112 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 013 12c0-1.605.42-3.113 1.157-4.418"
/>
</svg>
{$t("pages.wallet_create.for_rest")}
9 months ago
</button>
</div>
{/if}
<div class="row mt-5">
<Button
disabled
style="justify-content: left;"
on:click|once={enterINVITE}
class="choice-button text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
class="mr-4 block h-10 w-10"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M13.19 8.688a4.5 4.5 0 011.242 7.244l-4.5 4.5a4.5 4.5 0 01-6.364-6.364l1.757-1.757m13.35-.622l1.757-1.757a4.5 4.5 0 00-6.364-6.364l-4.5 4.5a4.5 4.5 0 001.242 7.244"
/>
</svg>
{$t("pages.wallet_create.enter_invite_link")}
9 months ago
</Button>
</div>
{#if false && mobile}
<div class="row mt-5">
<button
on:click|once={enterQRcode}
class="choice-button text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
><svg
class="mr-4 block h-10 w-10"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M3.75 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 013.75 9.375v-4.5zM3.75 14.625c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5a1.125 1.125 0 01-1.125-1.125v-4.5zM13.5 4.875c0-.621.504-1.125 1.125-1.125h4.5c.621 0 1.125.504 1.125 1.125v4.5c0 .621-.504 1.125-1.125 1.125h-4.5A1.125 1.125 0 0113.5 9.375v-4.5z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M6.75 6.75h.75v.75h-.75v-.75zM6.75 16.5h.75v.75h-.75v-.75zM16.5 6.75h.75v.75h-.75v-.75zM13.5 13.5h.75v.75h-.75v-.75zM13.5 19.5h.75v.75h-.75v-.75zM19.5 13.5h.75v.75h-.75v-.75zM19.5 19.5h.75v.75h-.75v-.75zM16.5 16.5h.75v.75h-.75v-.75z"
/>
</svg>
{$t("pages.wallet_create.scan_invite_qr")}
9 months ago
</button>
</div>
{/if}
<div class="row mt-5">
<button
9 months ago
on:click={displaySelfHost}
class="choice-button text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
class="mr-4 block h-10 w-10"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M5.25 14.25h13.5m-13.5 0a3 3 0 01-3-3m3 3a3 3 0 100 6h13.5a3 3 0 100-6m-16.5-3a3 3 0 013-3h13.5a3 3 0 013 3m-19.5 0a4.5 4.5 0 01.9-2.7L5.737 5.1a3.375 3.375 0 012.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 01.9 2.7m0 0a3 3 0 01-3 3m0 3h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008zm-3 6h.008v.008h-.008v-.008zm0-6h.008v.008h-.008v-.008z"
/>
</svg>
{$t("pages.wallet_create.self_hosted_broker")}
</button>
</div>
9 months ago
<div class="row mt-5 mb-12">
<button
9 months ago
on:click={displayNGbox}
class="choice-button text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mb-2"
>
<svg
xmlns="http://www.w3.org/2000/svg"
9 months ago
version="1.1"
viewBox="0 0 225 225"
class="mr-4 block h-10 w-10"
9 months ago
stroke="currentColor"
stroke-width="12"
fill="none"
>
<path
9 months ago
d="M 88.332599,179.77884 C 72.858008,177.42608 59.581081,170.564 48.8817,159.38898 36.800075,146.77026 30.396139,130.74266 30.396139,113.12381 c 0,-8.81477 1.466462,-16.772273 4.503812,-24.439156 3.697755,-9.333883 8.658122,-16.726264 15.988284,-23.827148 4.07992,-3.952299 5.699054,-5.267377 9.730928,-7.903581 10.263753,-6.710853 20.852276,-10.247623 32.861256,-10.976317 17.083161,-1.036581 33.737521,4.410501 47.100151,15.404873 1.30009,1.069669 2.35446,2.035155 2.34305,2.145524 -0.0114,0.110369 -3.32807,3.135042 -7.37038,6.721489 -4.04229,3.586437 -8.6667,7.731233 -10.27646,9.210635 -1.60975,1.479412 -3.05439,2.689839 -3.21032,2.689839 -0.15591,0 -1.2075,-0.642795 -2.33686,-1.428431 -6.49544,-4.518567 -13.79659,-6.747116 -22.104843,-6.747116 -10.982241,0 -20.054641,3.741852 -27.727158,11.435891 -5.517107,5.532575 -9.233107,12.555305 -10.782595,20.377588 -0.596045,3.00901 -0.594915,11.67153 0.0017,14.67182 3.195984,16.0665 15.801761,28.55358 31.607491,31.30987 3.592183,0.62643 10.334745,0.61437 13.792675,-0.0247 12.10383,-2.2368 22.30712,-9.80603 27.83192,-20.64689 0.66747,-1.30971 1.08703,-2.48825 0.93235,-2.61898 -0.1547,-0.13073 -5.9299,-1.01605 -12.83381,-1.96739 -8.43575,-1.16241 -12.87296,-1.9096 -13.52955,-2.27826 -1.31171,-0.73647 -2.44642,-2.49122 -2.44642,-3.78325 0,-1.012 1.74837,-13.68832 2.1486,-15.57814 0.25598,-1.20873 2.0923,-3.01339 3.3151,-3.25795 0.53677,-0.10735 7.61424,0.73799 15.7688,1.88346 8.13723,1.14303 14.89071,1.97925 15.00772,1.85826 0.11702,-0.12098 0.96445,-5.648553 1.88315,-12.283473 0.95557,-6.900944 1.90122,-12.59548 2.20977,-13.306594 0.29667,-0.683692 0.95765,-1.595052 1.46889,-2.025218 1.77972,-1.497534 2.7114,-1.539742 10.52745,-0.476938 8.31229,1.130266 9.2373,1.347581 10.59333,2.488613 1.41776,1.192951 1.96085,2.424677 1.94866,4.419342 -0.006,0.950347 -0.79507,7.156475 -1.75393,13.791395 -0.95885,6.634933 -1.70069,12.111623 -1.64854,12.170443 0.0522,0.0588 6.18174,0.95872 13.62132,1.99978 9.57969,1.34053 13.80866,2.0595 14.49353,2.46406 1.3199,0.77969 2.13943,2.28402 2.1135,3.87957 -0.0399,2.45278 -2.08103,15.63263 -2.5664,16.57122 -0.57073,1.10369 -2.24485,2.197 -3.38232,2.20889 -0.44831,0.004 -6.79249,-0.82755 -14.09817,-1.84941 -7.3057,-1.02186 -13.34942,-1.79161 -13.43049,-1.71053 -0.0811,0.0811 -1.02469,6.33285 -2.09694,13.89286 -1.24218,8.75802 -2.1547,14.1778 -2.51495,14.93697 -0.62565,1.31846 -2.38302,2.64205 -3.91461,2.94836 -0.8254,0.16509 -9.4024,-0.80047 -11.73007,-1.32049 -0.47193,-0.10544 -1.63157,0.58011 -3.8898,2.29957 -9.71515,7.39729 -20.99725,11.99799 -33.08692,13.49241 -3.79574,0.46921 -13.565667,0.37348 -17.125664,-0.16779 z"
/>
<rect
ry="37.596001"
y="10.583322"
x="14.363095"
height="204.86308"
width="195.79167"
/>
</svg>
{$t("pages.wallet_create.ng_box")}
</button>
</div>
9 months ago
{:else if pin.length < 4}
<div class=" max-w-6xl lg:px-8 mx-auto">
9 months ago
{#if registration_success}
<Alert color="green" class="mb-5">
<span class="font-bold text-xl"
>{$t("pages.wallet_create.registration_success", {
values: { broker: registration_success },
})}</span
9 months ago
>
</Alert>
{/if}
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="text-xl"
>{$t("pages.wallet_create.choose_pin.title")}</span
9 months ago
>
<Alert color="yellow" class="mt-5">
{@html $t("pages.wallet_create.choose_pin.description")}
9 months ago
</Alert>
</p>
<p class="text-left mt-5 px-3">
{$t("pages.wallet_create.choose_pin.rules")}
</p>
<ul class="text-left list-disc list-inside px-3">
<li>{@html $t("pages.wallet_create.choose_pin.1")}</li>
9 months ago
<li>
{@html $t("pages.wallet_create.choose_pin.2")}
9 months ago
</li>
<li>
{@html $t("pages.wallet_create.choose_pin.3")}
9 months ago
</li>
</ul>
9 months ago
<Alert color="blue" class="mt-5">
{$t("pages.wallet_create.chosen_pin")}
{#each pin as digit}<span class="font-bold text-xl">{digit}</span
9 months ago
>{/each}
</Alert>
9 months ago
<div class="w-[295px] mx-auto mb-10">
9 months ago
{#each [0, 1, 2] as row}
<div class="">
{#each [1, 2, 3] as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => sel_pin(num + row * 3)}
>
<span>{num + row * 3}</span>
</button>
{/each}
</div>
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => sel_pin(0)}
>
<span>0</span>
</button>
</div>
</div>
{:else if pin_confirm.length < 4}
<div class=" max-w-6xl lg:px-8 mx-auto px-3">
<p class="max-w-xl md:mx-auto lg:max-w-2xl">
<span class="text-red-800 text-xl"
>{$t("pages.wallet_create.confirm_pin")}</span
9 months ago
>
{$t("pages.wallet_create.confirm_pin_description")}
9 months ago
</p>
<Alert color="blue" class="mt-5">
{$t("pages.wallet_create.chosen_pin")}: {#each pin_confirm as digit}<span
9 months ago
class="font-bold text-xl">{digit}</span
>{/each}
</Alert>
<div class="w-[295px] mx-auto">
{#each [0, 1, 2] as row}
<div class="">
{#each [1, 2, 3] as num}
<button
tabindex="0"
class="m-1 select-none align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await confirm_pin(num + row * 3)}
>
<span>{num + row * 3}</span>
</button>
{/each}
</div>
{/each}
<button
tabindex="0"
class="m-1 select-none mx-auto align-bottom text-7xl w-[90px] h-[90px] p-0"
on:click={async () => await confirm_pin(0)}
>
<span>0</span>
</button>
</div>
</div>
{:else if !options}
<div class=" max-w-6xl lg:px-8 mx-auto px-4">
{#if pin.toString() === pin_confirm.toString()}
<Alert color="green" class="mt-5">
{$t("pages.wallet_create.pin_confirmed_as")}
{#each pin_confirm as digit}<span class="font-bold text-xl"
>{digit}</span
9 months ago
>{/each}
</Alert>
<h2 class="text-xl my-5">
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.title"
)}
9 months ago
</h2>
<p class="max-w-xl md:mx-auto lg:max-w-2xl text-left">
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.description"
)}
9 months ago
<Alert color="red" class="mt-5">
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.warning"
)}
9 months ago
</Alert>
</p>
<p
class="max-w-xl md:mx-auto lg:max-w-2xl text-left mt-5 text-sm"
>
{$t(
"pages.wallet_create.choose_security_phrase_and_image.rules_title"
)}
9 months ago
</p>
<ul
class="max-w-xl md:mx-auto lg:max-w-2xl text-left mt-5 text-sm list-disc list-inside"
>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.1"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.2"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.3"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.4"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.5"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.6"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.7"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.8"
)}
9 months ago
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.9"
)}
</li>
<li>
{@html $t(
"pages.wallet_create.choose_security_phrase_and_image.10"
)}
9 months ago
</li>
</ul>
9 months ago
<input
bind:this={phrase}
class="mt-10 mr-0"
id="security-phrase-input"
placeholder={$t(
"pages.wallet_create.type_security_phrase_placeholder"
)}
9 months ago
bind:value={security_txt}
on:keypress={security_phrase_ok}
/><button on:click={async () => await security_phrase_ok()}>
{$t("buttons.ok")}
9 months ago
</button><br />
{#if security_txt && security_img}
<button
on:click|once={save_security}
bind:this={validate_button}
class="animate-bounce mt-10 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M6.633 10.5c.806 0 1.533-.446 2.031-1.08a9.041 9.041 0 012.861-2.4c.723-.384 1.35-.956 1.653-1.715a4.498 4.498 0 00.322-1.672V3a.75.75 0 01.75-.75A2.25 2.25 0 0116.5 4.5c0 1.152-.26 2.243-.723 3.218-.266.558.107 1.282.725 1.282h3.126c1.026 0 1.945.694 2.054 1.715.045.422.068.85.068 1.285a11.95 11.95 0 01-2.649 7.521c-.388.482-.987.729-1.605.729H13.48c-.483 0-.964-.078-1.423-.23l-3.114-1.04a4.501 4.501 0 00-1.423-.23H5.904M14.25 9h2.25M5.904 18.75c.083.205.173.405.27.602.197.4-.078.898-.523.898h-.908c-.889 0-1.713-.518-1.972-1.368a12 12 0 01-.521-3.507c0-1.553.295-3.036.831-4.398C3.387 10.203 4.167 9.75 5 9.75h1.053c.472 0 .745.556.5.96a8.958 8.958 0 00-1.302 4.665c0 1.194.232 2.333.654 3.375z"
/>
</svg>
{$t("pages.wallet_create.save_security_phrase_and_image")}
9 months ago
</button>
{/if}
<Dropzone
class="mt-10 mb-10"
defaultClass="flex flex-col justify-center items-center w-full h-30 bg-gray-50 rounded-lg border-2 border-gray-300 border-dashed cursor-pointer dark:hover:bg-bray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600"
id="dropzone"
accept=".jpg, .jpeg, .png, .gif, .webp, .pnm, .tiff, .tif, .tga, .bmp, .avif, .qoi, .exr, .ppm"
on:drop={dropHandle}
on:dragover={(event) => {
event.preventDefault();
}}
on:change={handleChange}
>
<p class="mt-2 mb-5 text-gray-500 dark:text-gray-400">
{#if is_touch_device}
<span class="font-semibold"
>{$t("pages.wallet_create.tap_to_upload")}</span
>
9 months ago
{:else}
<span class="font-semibold"
>{$t("pages.wallet_create.click_to_upload")}</span
>
{$t("pages.wallet_create.or_drag_drop")}
9 months ago
{/if}
</p>
<svg
aria-hidden="true"
class="mb-3 w-20 mx-auto h-20 text-gray-400"
class:animate-bounce={animate_bounce}
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
><path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
/></svg
>
</Dropzone>
<img
bind:this={img_preview}
class="max-w-[250px] h-[250px] mx-auto mb-10"
src={image_url}
alt="your security"
/>
{:else}
<Alert color="red" class="mt-5">
{$t("pages.wallet_create.pins_no_match")}
9 months ago
</Alert>
<button
class="select-none"
on:click={async () => {
pin_confirm = [];
pin = [];
}}
>
{$t("buttons.start_over")}
9 months ago
</button>
{/if}
</div>
{:else if !creating}
<div class=" max-w-6xl lg:px-8 mx-auto px-4" bind:this={info_options}>
<p class="max-w-xl mb-10 md:mx-auto lg:max-w-2xl">
<span class="text-xl"
>{$t("pages.wallet_create.almost_done")}</span
><br />
{@html $t("pages.wallet_create.save_wallet_options.description")}
9 months ago
</p>
<p class="max-w-xl md:mx-auto lg:max-w-2xl text-left">
<span class="text-xl"
>{@html $t(
"pages.wallet_create.save_wallet_options.trust"
)}</span
><br />
{@html $t(
"pages.wallet_create.save_wallet_options.trust_description"
)}
{#if !tauri_platform}{@html $t(
9 months ago
"pages.login.trust_device_allow_cookies"
)}{/if}<br /><br />
<Toggle bind:checked={options.trusted}
>{@html $t(
"pages.wallet_create.save_wallet_options.trust_toggle"
)}</Toggle
9 months ago
>
</p>
<!-- Device Name -->
{#if options.trusted}
<br />
<p class="max-w-xl md:mx-auto lg:max-w-2xl text-left">
{@html $t(
"pages.wallet_create.save_wallet_options.device_name_description"
)}
</p>
<input
id="device-name-input"
8 months ago
class="mt-2 bg-gray-50 border border-gray-300 text-xs rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
bind:value={device_name}
placeholder={$t(
8 months ago
"pages.login.device_name_placeholder"
)}
type="text"
/>
{/if}
9 months ago
<p class="max-w-xl md:mx-auto mt-10 lg:max-w-2xl text-left">
<span class="text-xl"
>{@html $t(
"pages.wallet_create.save_wallet_options.cloud"
)}</span
> <br />
{@html $t(
"pages.wallet_create.save_wallet_options.cloud_description"
)}
9 months ago
<span
style="font-weight: 500;cursor: pointer; color: #646cff;"
tabindex="0"
role="link"
on:keypress={tos}
on:click={tos}
>{@html $t(
"pages.wallet_create.save_wallet_options.cloud_tos"
)}</span
9 months ago
>.
9 months ago
<br /><br />
<Toggle disabled bind:checked={options.cloud}
>{@html $t(
"pages.wallet_create.save_wallet_options.cloud_toggle"
)}</Toggle
9 months ago
>
</p>
<p class="max-w-xl md:mx-auto mt-10 lg:max-w-2xl text-left">
<span class="text-xl"
>{@html $t("pages.wallet_create.save_wallet_options.pdf")}</span
>
9 months ago
<br />
{@html $t(
"pages.wallet_create.save_wallet_options.pdf_description"
)}
9 months ago
<br /><br />
<Toggle disabled bind:checked={options.pdf}
>{@html $t(
"pages.wallet_create.save_wallet_options.pdf_toggle"
)}</Toggle
9 months ago
>
</p>
{#if !options.cloud}
<p class="max-w-xl md:mx-auto mt-10 lg:max-w-2xl text-left">
<span class="text-xl"
>{@html $t("pages.wallet_create.save_wallet_options.link")}
9 months ago
</span> <br />
{@html $t(
"pages.wallet_create.save_wallet_options.link_description"
)}
9 months ago
<span
style="font-weight: 500;cursor: pointer; color: #646cff;"
tabindex="0"
role="link"
on:keypress={tos}
on:click={tos}
>{@html $t(
"pages.wallet_create.save_wallet_options.cloud_tos"
)}</span
9 months ago
>.
9 months ago
<br /><br />
<Toggle disabled bind:checked={options.bootstrap}
>{@html $t(
"pages.wallet_create.save_wallet_options.link_toggle"
)}</Toggle
9 months ago
>
</p>
{/if}
<button
9 months ago
on:click|once={do_wallet}
class="mt-10 mb-20 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M9 12.75L11.25 15 15 9.75M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
{$t("pages.wallet_create.lets_create")}
</button>
</div>
9 months ago
{:else if !error}
{#if !ready}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-primary-700">
{$t("pages.wallet_create.creating")}
<Spinner className="mt-10 h-6 w-6 mx-auto" />
9 months ago
</div>
{:else}
<div class="text-left mx-4">
9 months ago
<div class="text-green-800 mx-auto flex flex-col items-center">
<div>{$t("pages.wallet_create.ready")}</div>
<svg
9 months ago
class="my-4 h-16 w-16"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M9 12.75L11.25 15 15 9.75M21 12c0 1.268-.63 2.39-1.593 3.068a3.745 3.745 0 01-1.043 3.296 3.745 3.745 0 01-3.296 1.043A3.745 3.745 0 0112 21c-1.268 0-2.39-.63-3.068-1.593a3.746 3.746 0 01-3.296-1.043 3.745 3.745 0 01-1.043-3.296A3.745 3.745 0 013 12c0-1.268.63-2.39 1.593-3.068a3.745 3.745 0 011.043-3.296 3.746 3.746 0 013.296-1.043A3.746 3.746 0 0112 3c1.268 0 2.39.63 3.068 1.593a3.746 3.746 0 013.296 1.043 3.746 3.746 0 011.043 3.296A3.745 3.745 0 0121 12z"
/>
</svg>
9 months ago
</div>
9 months ago
<div class="text-center">
{#if download_link}
{@html $t(
"pages.wallet_create.download_wallet_description"
)}<br />
<a
href={download_link}
target="_blank"
download={download_name}
9 months ago
>
<button
tabindex="-1"
class:animate-bounce={animateDownload}
on:click={() => (animateDownload = false)}
class="mt-10 mb-8 text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55"
9 months ago
>
<svg
class="w-8 h-8 mr-2 -ml-1"
fill="none"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M19.5 14.25v-2.625a3.375 3.375 0 00-3.375-3.375h-1.5A1.125 1.125 0 0113.5 7.125v-1.5a3.375 3.375 0 00-3.375-3.375H8.25m.75 12l3 3m0 0l3-3m-3 3v-6m-1.5-9H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 00-9-9z"
/>
</svg>
2 years ago
{@html $t("pages.wallet_create.download_wallet")}
</button>
</a>
9 months ago
9 months ago
<br />
{:else if !options.trusted}
{@html $t("pages.wallet_create.download_wallet_done", {
values: { download_name },
})}
9 months ago
{/if}
<!-- Pazzle -->
{@html $t("pages.wallet_create.your_pazzle")}
9 months ago
</div>
9 months ago
<div
class="mt-2 bg-white shadow-md rounded-lg max-w-2xl w-full mx-auto"
>
9 months ago
{#each pazzle_emojis as emoji, index}
<div
class="flex w-full p-1 tall-sm:p-2 content-center"
9 months ago
class:border-b={index !== pazzle_emojis.length - 1}
class:justify-center={!small_screen}
>
<div class="mr-4 content-center pt-1 my-auto">
{index + 1}
9 months ago
</div>
<div
9 months ago
class="flex justify-center w-[3em] h-[3em]"
title={$t("emojis.codes." + emoji.code)}
9 months ago
>
<svelte:component
this={emoji.svg?.default}
9 months ago
class="w-[3em] h-[3em] "
9 months ago
/>
</div>
<div class="flex flex-col ml-4">
<div class="w-[10em] text-left">
9 months ago
<span>{$t("emojis.category." + emoji.cat)}</span>
</div>
<div class="font-bold text-lg h-full content-center">
<span>{$t("emojis.codes." + emoji.code)}</span>
</div>
9 months ago
</div>
</div>
{/each}
</div>
<br />
9 months ago
<!-- Mnemonic (copy button). TODO: once the component is available-->
9 months ago
<label for="mnemonic"
>{@html $t("pages.wallet_create.your_mnemonic")}</label
>
9 months ago
<CopyToClipboard
id="mnemonic"
value={ready.mnemonic_str.join(" ")}
/>
9 months ago
<br />
{@html $t("pages.wallet_create.unlock_tips_1")}
9 months ago
<br /><br />
{@html $t("pages.wallet_create.unlock_tips_2")}
9 months ago
<br />
{@html $t("pages.wallet_create.unlock_tips_3", {
values: { platform: tauri_platform || "browser" },
})}
<br /><br />
9 months ago
<div class="flex flex-col items-center">
<button
tabindex="-1"
9 months ago
class="mb-20 text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2"
on:click={() => (confirm_modal_open = true)}
>
<svg
class="w-8 h-8 mr-2 -ml-1"
9 months ago
fill="currentColor"
stroke="currentColor"
9 months ago
stroke-width="2"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
9 months ago
d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z"
/>
</svg>
{$t("pages.wallet_create.continue_to_login")}
</button>
9 months ago
</div>
<Modal
autoclose
outsideclose
bind:open={confirm_modal_open}
title={$t("pages.wallet_create.continue_confirm")}
>
<span class="text-lg text-neutral-950">
{@html $t("pages.wallet_create.continue_confirm_description")}
</span>
9 months ago
<div>
<button
class="m-2"
on:click={() => (confirm_modal_open = false)}
>{$t(
"pages.wallet_create.continue_confirm_go_back"
)}</button
9 months ago
>
<a href="/wallet/login" use:link>
<button class="m-2 bg-primary-700 text-white"
>{$t("pages.wallet_create.continue_confirm_yes")}</button
9 months ago
>
</a>
</div>
</Modal>
</div>
{/if}
{:else}
<div class=" max-w-6xl lg:px-8 mx-auto px-4 text-red-800">
{$t("errors.an_error_occurred")}
9 months ago
<svg
fill="none"
class="animate-bounce mt-10 h-10 w-10 mx-auto"
stroke="currentColor"
stroke-width="1.5"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
aria-hidden="true"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126zM12 15.75h.007v.008H12v-.008z"
/>
</svg>
<Alert color="red" class="mt-5">
{$t("errors." + error)}
9 months ago
</Alert>
<button
class="mt-10 select-none"
on:click={async () => {
pin_confirm = [];
pin = [];
options = undefined;
creating = false;
error = undefined;
animateDownload = true;
}}
>
{$t("buttons.start_over")}
9 months ago
</button>
</div>
{/if}
9 months ago
</div>
{/if}
</div>
</CenteredLayout>
2 years ago
<style>
</style>