4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-11 17:55:51 +00:00

Merge branch 'master' into feature/new-editor-file-import

This commit is contained in:
Phillip 2023-02-09 17:38:17 +02:00
commit 5df8f227f8
129 changed files with 19776 additions and 16769 deletions

View File

@ -29,7 +29,7 @@ Easiest way to install the lastest required packages on Linux is via nvm.
``` nvm ls-remote ``` (Fetch list of available versions) <br/> ``` nvm ls-remote ``` (Fetch list of available versions) <br/>
``` nvm install v16.17.1 ``` (LTS: Gallium supported by Electron) <br/> ``` nvm install v16.17.1 ``` (LTS: Gallium supported by Electron) <br/>
``` npm --location=global install yarn@1.22.19 ``` <br/> ``` npm --location=global install yarn@1.22.19 ``` <br/>
``` npm --location=global install npm@9.2.0 ``` <br/> ``` npm --location=global install npm@9.3.1 ``` <br/>
On BSD do a ``` pkg_add node followed by npm install -g yarn ``` On BSD do a ``` pkg_add node followed by npm install -g yarn ```

BIN
img/badges/Level-8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
img/badges/level-10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
img/badges/level-6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
img/badges/level-7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
img/badges/level-9.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Актуализацията е готова за инсталиране", "electron_translate_7": "Актуализацията е готова за инсталиране",
"electron_translate_8": "Беше изтеглена нова версия на Qortal UI.", "electron_translate_8": "Беше изтеглена нова версия на Qortal UI.",
"electron_translate_9": "Щракнете върху ИНСТАЛИРАНЕ СЕГА, за да приложите актуализация, МОЖЕ БИ ПО-КЪСНО, за да не актуализирате потребителския интерфейс.", "electron_translate_9": "Щракнете върху ИНСТАЛИРАНЕ СЕГА, за да приложите актуализация, МОЖЕ БИ ПО-КЪСНО, за да не актуализирате потребителския интерфейс.",
"electron_translate_10": "Грешка при актуализиране...", "electron_translate_10": "Временна неуспешна актуализация, ще опитаме отново по-късно",
"electron_translate_11": "ИЗТЕГЛЕТЕ АКТУАЛИЗАЦИЯТА", "electron_translate_11": "ИЗТЕГЛЕТЕ АКТУАЛИЗАЦИЯТА",
"electron_translate_12": "Ще бъде изтеглено ⌛️ във фонов режим!" "electron_translate_12": "Ще бъде изтеглено ⌛️ във фонов режим!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Update zur Installation bereit", "electron_translate_7": "Update zur Installation bereit",
"electron_translate_8": "Eine neue Qortal-UI-Version wurde heruntergeladen.", "electron_translate_8": "Eine neue Qortal-UI-Version wurde heruntergeladen.",
"electron_translate_9": "Klicken Sie auf JETZT INSTALLIEREN, um das Update anzuwenden, VIELLEICHT SPÄTER, um die Benutzeroberfläche nicht zu aktualisieren.", "electron_translate_9": "Klicken Sie auf JETZT INSTALLIEREN, um das Update anzuwenden, VIELLEICHT SPÄTER, um die Benutzeroberfläche nicht zu aktualisieren.",
"electron_translate_10": "Fehler beim Aktualisieren...", "electron_translate_10": "Vorübergehender Aktualisierungsfehler, wir versuchen es später erneut",
"electron_translate_11": "UPDATE HERUNTERLADEN", "electron_translate_11": "UPDATE HERUNTERLADEN",
"electron_translate_12": "Das Update wird im Hintergrund heruntergeladen ⌛️!" "electron_translate_12": "Das Update wird im Hintergrund heruntergeladen ⌛️!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Update ready to install", "electron_translate_7": "Update ready to install",
"electron_translate_8": "A new Qortal UI version has been downloaded.", "electron_translate_8": "A new Qortal UI version has been downloaded.",
"electron_translate_9": "Click INSTALL NOW to apply update, MAYBE LATER to not update the UI.", "electron_translate_9": "Click INSTALL NOW to apply update, MAYBE LATER to not update the UI.",
"electron_translate_10": "Error while Updating...", "electron_translate_10": "Temporary update failure, will try again later",
"electron_translate_11": "DOWNLOAD UPDATE", "electron_translate_11": "DOWNLOAD UPDATE",
"electron_translate_12": "It will be downloaded ⌛️ in the background!" "electron_translate_12": "It will be downloaded ⌛️ in the background!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Actualización lista para instalar", "electron_translate_7": "Actualización lista para instalar",
"electron_translate_8": "Se ha descargado una nueva versión de la interfaz de usuario de Qortal.", "electron_translate_8": "Se ha descargado una nueva versión de la interfaz de usuario de Qortal.",
"electron_translate_9": "Haz clic en INSTALAR AHORA para aplicar la actualización, QUIZÁS MÁS TARDE para no actualizar la interfaz de usuario"., "electron_translate_9": "Haz clic en INSTALAR AHORA para aplicar la actualización, QUIZÁS MÁS TARDE para no actualizar la interfaz de usuario".,
"electron_translate_10": "Error al actualizar...", "electron_translate_10": "Error de actualización temporal, lo intentaré más tarde",
"electron_translate_11": "DESCARGAR ACTUALIZACIÓN", "electron_translate_11": "DESCARGAR ACTUALIZACIÓN",
"electron_translate_12": "¡Se descargará ⌛️ en segundo plano!" "electron_translate_12": "¡Se descargará ⌛️ en segundo plano!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Mise à jour prête à installer", "electron_translate_7": "Mise à jour prête à installer",
"electron_translate_8": "Une nouvelle version de l'interface utilisateur de Qortal a été téléchargée.", "electron_translate_8": "Une nouvelle version de l'interface utilisateur de Qortal a été téléchargée.",
"electron_translate_9": "Cliquez sur INSTALLER MAINTENANT pour appliquer la mise à jour, PEUT-ÊTRE PLUS TARD pour ne pas mettre à jour l'interface utilisateur.", "electron_translate_9": "Cliquez sur INSTALLER MAINTENANT pour appliquer la mise à jour, PEUT-ÊTRE PLUS TARD pour ne pas mettre à jour l'interface utilisateur.",
"electron_translate_10": "Erreur lors de la mise à jour...", "electron_translate_10": "Échec de la mise à jour temporaire, réessayera plus tard",
"electron_translate_11": "TÉLÉCHARGER LA MISE À JOUR", "electron_translate_11": "TÉLÉCHARGER LA MISE À JOUR",
"electron_translate_12": "Il sera téléchargé ⌛️ en arrière-plan !" "electron_translate_12": "Il sera téléchargé ⌛️ en arrière-plan !"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Aggiornamento pronto per l'installazione", "electron_translate_7": "Aggiornamento pronto per l'installazione",
"electron_translate_8": "È stata scaricata una nuova versione dell'interfaccia utente di Qortal.", "electron_translate_8": "È stata scaricata una nuova versione dell'interfaccia utente di Qortal.",
"electron_translate_9": "Fai clic su INSTALLA ORA per applicare l'aggiornamento, FORSE DOPO per non aggiornare l'interfaccia utente.", "electron_translate_9": "Fai clic su INSTALLA ORA per applicare l'aggiornamento, FORSE DOPO per non aggiornare l'interfaccia utente.",
"electron_translate_10": "Errore durante l'aggiornamento...", "electron_translate_10": "Errore di aggiornamento temporaneo, riproverà più tardi",
"electron_translate_11": "SCARICA AGGIORNAMENTO", "electron_translate_11": "SCARICA AGGIORNAMENTO",
"electron_translate_12": "Verrà scaricato ⌛️ in background!" "electron_translate_12": "Verrà scaricato ⌛️ in background!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "업데이트 설치 준비 완료", "electron_translate_7": "업데이트 설치 준비 완료",
"electron_translate_8": "새로운 Qortal UI 버전이 다운로드되었습니다.", "electron_translate_8": "새로운 Qortal UI 버전이 다운로드되었습니다.",
"electron_translate_9": "업데이트를 적용하려면 지금 설치를 클릭하고 UI를 업데이트하지 않으려면 나중에 할 수도 있습니다.", "electron_translate_9": "업데이트를 적용하려면 지금 설치를 클릭하고 UI를 업데이트하지 않으려면 나중에 할 수도 있습니다.",
"electron_translate_10": "업데이트 중 오류...", "electron_translate_10": "임시 업데이트 실패, 나중에 다시 시도합니다.",
"electron_translate_11": "업데이트 다운로드", "electron_translate_11": "업데이트 다운로드",
"electron_translate_12": "백그라운드에서 ⌛️ 다운로드됩니다!" "electron_translate_12": "백그라운드에서 ⌛️ 다운로드됩니다!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Update klaar om te installeren", "electron_translate_7": "Update klaar om te installeren",
"electron_translate_8": "Er is een nieuwe Qortal UI-versie gedownload.", "electron_translate_8": "Er is een nieuwe Qortal UI-versie gedownload.",
"electron_translate_9": "Klik op NU INSTALLEREN om de update toe te passen, MISSCHIEN LATER om de gebruikersinterface niet bij te werken.", "electron_translate_9": "Klik op NU INSTALLEREN om de update toe te passen, MISSCHIEN LATER om de gebruikersinterface niet bij te werken.",
"electron_translate_10": "Fout tijdens updaten...", "electron_translate_10": "Tijdelijke update mislukt, zal het later opnieuw proberen",
"electron_translate_11": "UPDATE DOWNLOADEN", "electron_translate_11": "UPDATE DOWNLOADEN",
"electron_translate_12": "Het wordt ⌛️ op de achtergrond gedownload!" "electron_translate_12": "Het wordt ⌛️ op de achtergrond gedownload!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Atualização pronta para instalar", "electron_translate_7": "Atualização pronta para instalar",
"electron_translate_8": "Uma nova versão Qortal UI foi baixada.", "electron_translate_8": "Uma nova versão Qortal UI foi baixada.",
"electron_translate_9": "Clique em INSTALAR AGORA para aplicar a atualização, TALVEZ MAIS TARDE para não atualizar a UI.", "electron_translate_9": "Clique em INSTALAR AGORA para aplicar a atualização, TALVEZ MAIS TARDE para não atualizar a UI.",
"electron_translate_10": "Erro ao atualizar...", "electron_translate_10": "Falha de atualização temporária, tentará novamente mais tarde",
"electron_translate_11": "BAIXAR ATUALIZAÇÃO", "electron_translate_11": "BAIXAR ATUALIZAÇÃO",
"electron_translate_12": "Será baixado ⌛️ em segundo plano!" "electron_translate_12": "Será baixado ⌛️ em segundo plano!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Atualização pronta para instalar", "electron_translate_7": "Atualização pronta para instalar",
"electron_translate_8": "Uma nova versão Qortal UI foi baixada.", "electron_translate_8": "Uma nova versão Qortal UI foi baixada.",
"electron_translate_9": "Clique em INSTALAR AGORA para aplicar a atualização, TALVEZ MAIS TARDE para não atualizar a UI.", "electron_translate_9": "Clique em INSTALAR AGORA para aplicar a atualização, TALVEZ MAIS TARDE para não atualizar a UI.",
"electron_translate_10": "Erro ao atualizar...", "electron_translate_10": "Falha de atualização temporária, tentará novamente mais tarde",
"electron_translate_11": "BAIXAR ATUALIZAÇÃO", "electron_translate_11": "BAIXAR ATUALIZAÇÃO",
"electron_translate_12": "Será baixado ⌛️ em segundo plano!" "electron_translate_12": "Será baixado ⌛️ em segundo plano!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Обновление готово к установке", "electron_translate_7": "Обновление готово к установке",
"electron_translate_8": "Загружена новая версия пользовательского интерфейса Qortal.", "electron_translate_8": "Загружена новая версия пользовательского интерфейса Qortal.",
"electron_translate_9": "Нажмите УСТАНОВИТЬ СЕЙЧАС, чтобы применить обновление, МОЖЕТ БЫТЬ ПОЗЖЕ, чтобы не обновлять пользовательский интерфейс.", "electron_translate_9": "Нажмите УСТАНОВИТЬ СЕЙЧАС, чтобы применить обновление, МОЖЕТ БЫТЬ ПОЗЖЕ, чтобы не обновлять пользовательский интерфейс.",
"electron_translate_10": "Ошибка при обновлении...", "electron_translate_10": "Временная ошибка обновления, повторите попытку позже",
"electron_translate_11": "СКАЧАТЬ ОБНОВЛЕНИЕ", "electron_translate_11": "СКАЧАТЬ ОБНОВЛЕНИЕ",
"electron_translate_12": "Он будет загружен ⌛️ в фоновом режиме!" "electron_translate_12": "Он будет загружен ⌛️ в фоновом режиме!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Güncelleme yüklenmeye hazır", "electron_translate_7": "Güncelleme yüklenmeye hazır",
"electron_translate_8": "Yeni bir Qortal UI sürümü indirildi.", "electron_translate_8": "Yeni bir Qortal UI sürümü indirildi.",
"electron_translate_9": "Güncellemeyi uygulamak için ŞİMDİ YÜKLE'ye tıklayın, kullanıcı arayüzünü güncellememek için MAYBE SONRA tıklayın.", "electron_translate_9": "Güncellemeyi uygulamak için ŞİMDİ YÜKLE'ye tıklayın, kullanıcı arayüzünü güncellememek için MAYBE SONRA tıklayın.",
"electron_translate_10": "Güncelleme Sırasında Hata...", "electron_translate_10": "Geçici güncelleme hatası, daha sonra tekrar denenecek",
"electron_translate_11": "GÜNCELLEMEYİ İNDİRİN", "electron_translate_11": "GÜNCELLEMEYİ İNDİRİN",
"electron_translate_12": "Arka planda ⌛️ indirilecek!" "electron_translate_12": "Arka planda ⌛️ indirilecek!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "Update ready to install", "electron_translate_7": "Update ready to install",
"electron_translate_8": "A new Qortal UI version has been downloaded.", "electron_translate_8": "A new Qortal UI version has been downloaded.",
"electron_translate_9": "Click INSTALL NOW to apply update, MAYBE LATER to not update the UI.", "electron_translate_9": "Click INSTALL NOW to apply update, MAYBE LATER to not update the UI.",
"electron_translate_10": "Error while Updating...", "electron_translate_10": "Temporary update failure, will try again later",
"electron_translate_11": "DOWNLOAD UPDATE", "electron_translate_11": "DOWNLOAD UPDATE",
"electron_translate_12": "It will be downloaded ⌛️ in the background!" "electron_translate_12": "It will be downloaded ⌛️ in the background!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "更新准备安装", "electron_translate_7": "更新准备安装",
"electron_translate_8": "已下载新的 Qortal UI 版本。", "electron_translate_8": "已下载新的 Qortal UI 版本。",
"electron_translate_9": "点击现在安装应用更新,可能稍后不更新用户界面。", "electron_translate_9": "点击现在安装应用更新,可能稍后不更新用户界面。",
"electron_translate_10": "更新时出错...", "electron_translate_10": "暂时更新失败,稍后再试",
"electron_translate_11": "下载更新", "electron_translate_11": "下载更新",
"electron_translate_12": "它将在后台下载 ⌛️!" "electron_translate_12": "它将在后台下载 ⌛️!"
} }

View File

@ -10,7 +10,7 @@
"electron_translate_7": "更新準備安裝", "electron_translate_7": "更新準備安裝",
"electron_translate_8": "已下載新的 Qortal UI 版本。", "electron_translate_8": "已下載新的 Qortal UI 版本。",
"electron_translate_9": "點擊現在安裝應用更新,可能稍後不更新用戶界面。", "electron_translate_9": "點擊現在安裝應用更新,可能稍後不更新用戶界面。",
"electron_translate_10": "更新時出錯...", "electron_translate_10": "暫時更新失敗,稍後再試",
"electron_translate_11": "下載更新", "electron_translate_11": "下載更新",
"electron_translate_12": "它將在後台下載 ⌛️!" "electron_translate_12": "它將在後台下載 ⌛️!"
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "qortal-ui", "name": "qortal-ui",
"version": "2.2.4", "version": "3.0.1",
"description": "Qortal Project - decentralize the world - Data storage, communications, web hosting, decentralized trading, complete infrastructure for the future blockchain-based Internet", "description": "Qortal Project - decentralize the world - Data storage, communications, web hosting, decentralized trading, complete infrastructure for the future blockchain-based Internet",
"keywords": [ "keywords": [
"QORT", "QORT",
@ -37,12 +37,9 @@
"os-locale": "3.0.0" "os-locale": "3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@electron/notarize": "1.2.3", "electron": "22.2.0",
"electron": "22.0.0",
"electron-builder": "23.6.0", "electron-builder": "23.6.0",
"electron-packager": "17.1.1", "electron-packager": "17.1.1",
"eslint-plugin-lit": "1.8.0",
"eslint-plugin-wc": "1.4.0",
"shelljs": "0.8.5" "shelljs": "0.8.5"
}, },
"engines": { "engines": {

View File

@ -9,7 +9,8 @@ html {
--copybutton: #707584; --copybutton: #707584;
--chat-group: #080808; --chat-group: #080808;
--chat-bubble: #9f9f9f0a; --chat-bubble: #9f9f9f0a;
--chat-bubble-bg: #f3f3f3; --chat-bubble-bg: #e6e6e6;
--chat-bubble-myBg: #d1ddf2;
--chat-bubble-msg-color: #080808; --chat-bubble-msg-color: #080808;
--reaction-bubble-outline: #6b6969; --reaction-bubble-outline: #6b6969;
--chat-menu-bg: #ffffff; --chat-menu-bg: #ffffff;
@ -28,6 +29,7 @@ html {
--relaynodetxt: #646464; --relaynodetxt: #646464;
--menuhover: #eeeeee; --menuhover: #eeeeee;
--menuactive: #ebebeb; --menuactive: #ebebeb;
--menuactivergb: 235, 235, 235;
--mainmenutext: #080808; --mainmenutext: #080808;
--mainmenutexthover: #080808; --mainmenutexthover: #080808;
--switchbackground: #666666; --switchbackground: #666666;
@ -50,6 +52,7 @@ html {
--lightChatHeadHover: #1e1f201a; --lightChatHeadHover: #1e1f201a;
--group-header: #929292; --group-header: #929292;
--group-drop-shadow: rgb(17 17 26 / 10%) 0px 1px 0px; --group-drop-shadow: rgb(17 17 26 / 10%) 0px 1px 0px;
--reactions-tooltip-bg: #ffffff;
} }
html[theme="dark"] { html[theme="dark"] {
@ -64,6 +67,7 @@ html[theme="dark"] {
--chat-group: #ffffff; --chat-group: #ffffff;
--chat-bubble: #9694941a; --chat-bubble: #9694941a;
--chat-bubble-bg: #2d3749; --chat-bubble-bg: #2d3749;
--chat-bubble-myBg: #40444d;
--chat-bubble-msg-color: #ffffff; --chat-bubble-msg-color: #ffffff;
--reaction-bubble-outline: #ffffff; --reaction-bubble-outline: #ffffff;
--chat-menu-bg: #32394c; --chat-menu-bg: #32394c;
@ -82,6 +86,7 @@ html[theme="dark"] {
--relaynodetxt: #d4d4d4; --relaynodetxt: #d4d4d4;
--menuhover: #008fd5; --menuhover: #008fd5;
--menuactive: #008fd5; --menuactive: #008fd5;
--menuactivergb: 0, 143, 213;
--mainmenutext: #008fd5; --mainmenutext: #008fd5;
--mainmenutexthover: #0f1a2e; --mainmenutexthover: #0f1a2e;
--switchbackground: #eeeeee; --switchbackground: #eeeeee;
@ -103,5 +108,6 @@ html[theme="dark"] {
--chatHeadTextActive: #ffffff; --chatHeadTextActive: #ffffff;
--lightChatHeadHover: #e0e1e31a; --lightChatHeadHover: #e0e1e31a;
--group-header: #c8c8c8; --group-header: #c8c8c8;
--group-drop-shadow: rgb(191 191 191 / 32%) 0px 1px 0px --group-drop-shadow: rgb(191 191 191 / 32%) 0px 1px 0px;
--reactions-tooltip-bg: #161515;
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,9 +17,9 @@
"author": "QORTAL <admin@qortal.org>", "author": "QORTAL <admin@qortal.org>",
"license": "GPL-3.0", "license": "GPL-3.0",
"dependencies": { "dependencies": {
"@hapi/hapi": "21.2.0", "@hapi/hapi": "21.2.1",
"@hapi/inert": "7.0.0", "@hapi/inert": "7.0.0",
"sass": "1.57.1" "sass": "1.58.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.20.12", "@babel/core": "7.20.12",
@ -58,23 +58,23 @@
"@rollup/plugin-commonjs": "24.0.1", "@rollup/plugin-commonjs": "24.0.1",
"@rollup/plugin-node-resolve": "15.0.1", "@rollup/plugin-node-resolve": "15.0.1",
"@rollup/plugin-replace": "5.0.2", "@rollup/plugin-replace": "5.0.2",
"@rollup/plugin-terser": "0.3.0", "@rollup/plugin-terser": "0.4.0",
"@vaadin/button": "23.3.5", "@vaadin/button": "23.3.6",
"@vaadin/grid": "23.3.5", "@vaadin/grid": "23.3.6",
"@vaadin/icons": "23.3.5", "@vaadin/icons": "23.3.6",
"@vaadin/password-field": "23.3.5", "@vaadin/password-field": "23.3.6",
"@vaadin/tooltip": "23.3.5", "@vaadin/tooltip": "23.3.6",
"asmcrypto.js": "2.3.2", "asmcrypto.js": "2.3.2",
"bcryptjs": "2.4.3", "bcryptjs": "2.4.3",
"epml": "0.3.3", "epml": "0.3.3",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"lit": "2.6.1", "lit": "2.6.1",
"lit-translate": "2.0.1", "lit-translate": "2.0.1",
"localforage": "1.10.0",
"pwa-helpers": "0.9.1", "pwa-helpers": "0.9.1",
"random-sentence-generator": "0.0.8", "redux": "4.2.1",
"redux": "4.2.0",
"redux-thunk": "2.4.2", "redux-thunk": "2.4.2",
"rollup": "3.10.1", "rollup": "3.14.0",
"rollup-plugin-node-globals": "1.4.0", "rollup-plugin-node-globals": "1.4.0",
"rollup-plugin-progress": "1.1.2", "rollup-plugin-progress": "1.1.2",
"rollup-plugin-scss": "3.0.0", "rollup-plugin-scss": "3.0.0",

View File

@ -4,6 +4,11 @@ import { store } from '../store.js'
import { Epml } from '../epml.js' import { Epml } from '../epml.js'
import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes.js' import { addTradeBotRoutes } from '../tradebot/addTradeBotRoutes.js'
import { get, translate, translateUnsafeHTML } from 'lit-translate' import { get, translate, translateUnsafeHTML } from 'lit-translate'
import localForage from "localforage";
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
});
import '@polymer/paper-icon-button/paper-icon-button.js' import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/paper-progress/paper-progress.js' import '@polymer/paper-progress/paper-progress.js'
@ -27,6 +32,7 @@ import './user-info-view/user-info-view.js'
import '../functional-components/side-menu.js' import '../functional-components/side-menu.js'
import '../functional-components/side-menu-item.js' import '../functional-components/side-menu-item.js'
import './start-minting.js' import './start-minting.js'
import { setChatLastSeen } from '../redux/app/app-actions.js'
const parentEpml = new Epml({type: 'WINDOW', source: window.parent}) const parentEpml = new Epml({type: 'WINDOW', source: window.parent})
@ -207,7 +213,7 @@ class AppView extends connect(store)(LitElement) {
#balanceheader { #balanceheader {
flex: 0 0 24px; flex: 0 0 24px;
padding: 12px 12px 20px 12px; padding: 12px 12px 45px 12px;
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--border);
background: var(--sidetopbar); background: var(--sidetopbar);
} }
@ -329,7 +335,16 @@ class AppView extends connect(store)(LitElement) {
.sideBarMenu::-webkit-scrollbar-thumb:hover { .sideBarMenu::-webkit-scrollbar-thumb:hover {
background-color: rgb(148, 146, 146); background-color: rgb(148, 146, 146);
cursor: pointer; cursor: pointer;
} }
.balanceButton {
background-color: #03a9f4;
color: #ffffff;
margin-left: 12px;
margin-right: 12px;
padding-top: 5px;
padding-bottom: 5px;
}
` `
] ]
} }
@ -426,6 +441,8 @@ class AppView extends connect(store)(LitElement) {
</side-menu> </side-menu>
</div> </div>
</div> </div>
<button class="balanceButton" @click="${() => this.shBalanceTicker()}">${translate("grouppage.gchange59")}</button>
<div id="theTicker" style="display: none; margin-bottom: 20px;">
<div id="balanceheader"> <div id="balanceheader">
<span class="balanceheadertext"> <span class="balanceheadertext">
${this.getAllBalancesLoading ? html` ${this.getAllBalancesLoading ? html`
@ -441,6 +458,7 @@ class AppView extends connect(store)(LitElement) {
</div> </div>
${this.getAllBalancesLoading ? html`<paper-progress indeterminate style="width: 100%; margin: 4px;"></paper-progress>` : ''} ${this.getAllBalancesLoading ? html`<paper-progress indeterminate style="width: 100%; margin: 4px;"></paper-progress>` : ''}
${this.balanceTicker} ${this.balanceTicker}
</div>
<app-info></app-info> <app-info></app-info>
</div> </div>
</app-header-layout> </app-header-layout>
@ -1386,6 +1404,17 @@ class AppView extends connect(store)(LitElement) {
} }
} }
const getChatLastSeen=async() => {
let items = [];
await chatLastSeen.iterate(function(value, key, iterationNumber) {
items.push({key, timestamp: value});
})
store.dispatch(setChatLastSeen(items))
return items;
}
await getOpenTradesBTC() await getOpenTradesBTC()
await appDelay(1000) await appDelay(1000)
await getOpenTradesLTC() await getOpenTradesLTC()
@ -1397,6 +1426,16 @@ class AppView extends connect(store)(LitElement) {
await getOpenTradesRVN() await getOpenTradesRVN()
await appDelay(1000) await appDelay(1000)
await getOpenTradesARRR() await getOpenTradesARRR()
await getChatLastSeen()
}
shBalanceTicker() {
const targetDiv = this.shadowRoot.getElementById("theTicker")
if (targetDiv.style.display !== "none") {
targetDiv.style.display = "none";
} else {
targetDiv.style.display = "inline";
}
} }
async getNodeType() { async getNodeType() {

View File

@ -4,11 +4,13 @@ import { store } from '../../store.js'
import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate' import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
import { createWallet } from '../../../../qortal-ui-crypto/api/createWallet.js' import { createWallet } from '../../../../qortal-ui-crypto/api/createWallet.js'
import FileSaver from 'file-saver'
import { doLogin, doLogout, doSelectAddress } from '../../redux/app/app-actions.js' import { doLogin, doLogout, doSelectAddress } from '../../redux/app/app-actions.js'
import { doStoreWallet } from '../../redux/user/user-actions.js' import { doStoreWallet } from '../../redux/user/user-actions.js'
import { checkApiKey } from '../../apiKeyUtils.js' import { checkApiKey } from '../../apiKeyUtils.js'
import FileSaver from 'file-saver'
import ripple from '../../functional-components/loading-ripple.js'
import snackbar from '../../functional-components/snackbar.js' import snackbar from '../../functional-components/snackbar.js'
import '../../functional-components/random-sentence-generator.js'
import '@material/mwc-button' import '@material/mwc-button'
import '@material/mwc-checkbox' import '@material/mwc-checkbox'
import '@material/mwc-textfield' import '@material/mwc-textfield'
@ -22,8 +24,6 @@ import '@polymer/paper-input/paper-input.js'
import '@polymer/paper-tooltip/paper-tooltip.js' import '@polymer/paper-tooltip/paper-tooltip.js'
import '@vaadin/text-field/vaadin-text-field.js' import '@vaadin/text-field/vaadin-text-field.js'
import '@vaadin/password-field/vaadin-password-field.js' import '@vaadin/password-field/vaadin-password-field.js'
import 'random-sentence-generator'
import ripple from '../../functional-components/loading-ripple.js'
let lastPassword = '' let lastPassword = ''
@ -393,17 +393,17 @@ class CreateAccountSection extends connect(store)(LitElement) {
</random-sentence-generator> </random-sentence-generator>
</div> </div>
<!-- <!--
--- --- --- --- --- --- --- --- --- --- --- - --- --- --- --- --- --- --- --- --- --- --- --- --- -
Calculations Calculations
--- --- --- --- --- --- --- --- --- --- --- - --- --- --- --- --- --- --- --- --- --- --- --- --- -
403 adjectives 403 adjectives
60 interjections 60 interjections
243 adverbs 243 adverbs
2353 nouns 2353 nouns
3387 verbs 3387 verbs
--- --- --- --- --- --- --- --- --- --- --- - --- --- --- --- --- --- --- --- --- --- --- --- --- -
sooo 243*3387*403*2353*3387*403*2353*403*2353 ~ 2^92 sooo 243*3387*403*2353*3387*403*2353*403*2353 ~ 2^92
--- --- --- --- --- --- --- --- --- --- --- - --- --- --- --- --- --- --- --- --- --- --- --- --- -
--> -->
</div><br> </div><br>
<div class="horizontal-center"> <div class="horizontal-center">

View File

@ -14,8 +14,15 @@ import './login-section.js'
import '../qort-theme-toggle.js' import '../qort-theme-toggle.js'
import settings from '../../functional-components/settings-page.js' import settings from '../../functional-components/settings-page.js'
import { addAutoLoadImageChat, removeAutoLoadImageChat, addChatLastSeen } from '../../redux/app/app-actions.js'
window.reduxStore = store window.reduxStore = store
window.reduxAction = {
addAutoLoadImageChat: addAutoLoadImageChat,
removeAutoLoadImageChat: removeAutoLoadImageChat,
addChatLastSeen: addChatLastSeen
}
const animationDuration = 0.7 // Seconds const animationDuration = 0.7 // Seconds

View File

@ -1171,7 +1171,7 @@ class UserInfoView extends connect(store)(LitElement) {
</div> </div>
</paper-dialog> </paper-dialog>
<paper-dialog style="background: var(--white); border: 1px solid var(--black); border-radius: 5px;" id="userBoughtDialog" modal> <paper-dialog style="background: var(--white); border: 1px solid var(--black); border-radius: 5px;" id="userBoughtDialog">
<div class="card-explorer-container"> <div class="card-explorer-container">
<div id="first-explorer-section"> <div id="first-explorer-section">
${this.boughtBTCTemplate()} ${this.boughtBTCTemplate()}
@ -1191,7 +1191,7 @@ class UserInfoView extends connect(store)(LitElement) {
</div> </div>
</paper-dialog> </paper-dialog>
<paper-dialog style="background: var(--white); border: 1px solid var(--black); border-radius: 5px; overflow: auto;" id="userSoldDialog" modal> <paper-dialog style="background: var(--white); border: 1px solid var(--black); border-radius: 5px; overflow: auto;" id="userSoldDialog">
<div class="card-explorer-container"> <div class="card-explorer-container">
<div id="first-explorer-section"> <div id="first-explorer-section">
${this.soldBTCTemplate()} ${this.soldBTCTemplate()}

View File

@ -0,0 +1,160 @@
// Author: irontiga <irontiga@gmail.com>
'use strict'
import { LitElement, html, css } from 'lit'
import * as WORDLISTS from './wordlists.js'
class RandomSentenceGenerator extends LitElement {
static get properties() {
return {
template: {
type: String,
attribute: 'template'
},
parsedString: {
type: String
},
fetchedWordlistCount: {
type: Number,
value: 0
},
capitalize: {
type: Boolean
},
partsOfSpeechMap: {
type: Object
},
templateEntropy: {
type: Number,
reflect: true,
attribute: 'template-entropy'
},
maxWordLength: {
type: Number,
attribute: 'max-word-length'
}
}
}
constructor() {
super()
this.template = 'adjective noun verb adverb.'
this.maxWordLength = 0
this.parsedString = ''
this.fetchedWordlistCount = 0
this.capitalize = true
this.partsOfSpeechMap = {
'noun': 'nouns',
'adverb': 'adverbs',
'adv': 'adverbs',
'verb': 'verbs',
'interjection': 'interjections',
'adjective': 'adjectives',
'adj': 'adjectives',
'verbed': 'verbed'
}
this.partsOfSpeech = Object.keys(this.partsOfSpeechMap)
this._wordlists = WORDLISTS
}
updated(changedProperties) {
let regen = false
if (changedProperties.has('template')) {
regen = true
}
if (changedProperties.has('maxWordLength')) {
console.dir(this.maxWordLength)
if (this.maxWordLength) {
const wl = { ...this._wordlists }
for (const partOfSpeech in this._wordlists) {
console.log(this._wordlists[partOfSpeech])
if (Array.isArray(this._wordlists[partOfSpeech])) {
wl[partOfSpeech] = this._wordlists[partOfSpeech].filter(word => word.length <= this.maxWordLength)
}
}
this._wordlists = wl
}
regen = true
}
if (regen) this.generate()
}
_RNG(entropy) {
if (entropy > 1074) {
throw new Error('Javascript can not handle that much entropy!')
}
let randNum = 0
const crypto = window.crypto || window.msCrypto
if (crypto) {
const entropy256 = Math.ceil(entropy / 8)
let buffer = new Uint8Array(entropy256)
crypto.getRandomValues(buffer)
randNum = buffer.reduce((num, value) => {
return num * value
}, 1) / Math.pow(256, entropy256)
} else {
console.warn('Secure RNG not found. Using Math.random')
randNum = Math.random()
}
return randNum
}
setRNG(fn) {
this._RNG = fn
}
_captitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1)
}
getWord(partOfSpeech) {
const words = this._wordlists[this.partsOfSpeechMap[partOfSpeech]]
const requiredEntropy = Math.log(words.length) / Math.log(2)
const index = this._RNG(requiredEntropy) * words.length
return {
word: words[Math.round(index)],
entropy: words.length
}
}
generate() {
this.parsedString = this.parse(this.template)
}
parse(template) {
const split = template.split(/[\s]/g)
let entropy = 1
const final = split.map(word => {
const lower = word.toLowerCase()
this.partsOfSpeech.some(partOfSpeech => {
const partOfSpeechIndex = lower.indexOf(partOfSpeech) // Check it exists
const nextChar = word.charAt(partOfSpeech.length)
if (partOfSpeechIndex === 0 && !(nextChar && (nextChar.match(/[a-zA-Z]/g) != null))) {
const replacement = this.getWord(partOfSpeech)
word = replacement.word + word.slice(partOfSpeech.length) // Append the rest of the "word" (punctuation)
entropy = entropy * replacement.entropy
return true
}
})
return word
})
this.templateEntropy = Math.floor(Math.log(entropy) / Math.log(8))
return final.join(' ')
}
render() {
return html`
${this.parsedString}
`
}
}
customElements.define('random-sentence-generator', RandomSentenceGenerator)
export default RandomSentenceGenerator

View File

@ -0,0 +1,36 @@
// Sourced from https://gist.github.com/letsgetrandy/1e05a68ea74ba6736eb5
export const EXCEPTIONS = {
'are': 'were',
'eat': 'ate',
'go': 'went',
'have': 'had',
'inherit': 'inherited',
'is': 'was',
'run': 'ran',
'sit': 'sat',
'visit': 'visited'
}
export const getPastTense = (verb, exceptions = EXCEPTIONS) => {
if (exceptions[verb]) {
return exceptions[verb]
}
if ((/e$/i).test(verb)) {
return verb + 'd'
}
if ((/[aeiou]c$/i).test(verb)) {
return verb + 'ked'
}
// for american english only
if ((/el$/i).test(verb)) {
return verb + 'ed'
}
if ((/[aeio][aeiou][dlmnprst]$/).test(verb)) {
return verb + 'ed'
}
if ((/[aeiou][bdglmnprst]$/i).test(verb)) {
return verb.replace(/(.+[aeiou])([bdglmnprst])/, '$1$2$2ed')
}
return verb + 'ed'
}

File diff suppressed because one or more lines are too long

View File

@ -2,7 +2,6 @@ import { store } from '../../store.js'
import { doPageUrl } from '../../redux/app/app-actions.js' import { doPageUrl } from '../../redux/app/app-actions.js'
export const newMessage = (data) => { export const newMessage = (data) => {
const alert = playSound(data.sound) const alert = playSound(data.sound)
// Should I show notification ? // Should I show notification ?
@ -18,7 +17,7 @@ export const newMessage = (data) => {
} }
notify.onclick = (e) => { notify.onclick = (e) => {
const pageUrl = `/app/q-chat/${data.req.url}` const pageUrl = `/app/q-chat/?chat=${data.req.url}`
store.dispatch(doPageUrl(pageUrl)) store.dispatch(doPageUrl(pageUrl))
} }
} else { } else {
@ -26,7 +25,7 @@ export const newMessage = (data) => {
const notify = new Notification(data.title, data.options) const notify = new Notification(data.title, data.options)
notify.onclick = (e) => { notify.onclick = (e) => {
const pageUrl = `/app/q-chat/${data.req.url}` const pageUrl = `/app/q-chat/?chat=${data.req.url}`
store.dispatch(doPageUrl(pageUrl)) store.dispatch(doPageUrl(pageUrl))
} }
} }

View File

@ -9,6 +9,7 @@ const CHAT_HEADS_STREAM_NAME = 'chat_heads'
const NODE_CONFIG_STREAM_NAME = 'node_config' const NODE_CONFIG_STREAM_NAME = 'node_config'
const COPY_MENU_SWITCH = 'copy_menu_switch' const COPY_MENU_SWITCH = 'copy_menu_switch'
const FRAME_PASTE_MENU_SWITCH = 'frame_paste_menu_switch' const FRAME_PASTE_MENU_SWITCH = 'frame_paste_menu_switch'
const CHAT_LAST_SEEN = 'chat_last_seen'
export const loggedInStream = new EpmlStream(LOGIN_STREAM_NAME, () => store.getState().app.loggedIn) export const loggedInStream = new EpmlStream(LOGIN_STREAM_NAME, () => store.getState().app.loggedIn)
export const configStream = new EpmlStream(CONFIG_STREAM_NAME, () => store.getState().config) export const configStream = new EpmlStream(CONFIG_STREAM_NAME, () => store.getState().config)
@ -18,6 +19,7 @@ export const chatHeadsStateStream = new EpmlStream(CHAT_HEADS_STREAM_NAME, () =>
export const nodeConfigStream = new EpmlStream(NODE_CONFIG_STREAM_NAME, () => store.getState().app.nodeConfig) export const nodeConfigStream = new EpmlStream(NODE_CONFIG_STREAM_NAME, () => store.getState().app.nodeConfig)
export const copyMenuSwitchStream = new EpmlStream(COPY_MENU_SWITCH, () => store.getState().app.copyMenuSwitch) export const copyMenuSwitchStream = new EpmlStream(COPY_MENU_SWITCH, () => store.getState().app.copyMenuSwitch)
export const framePasteMenuSwitchStream = new EpmlStream(FRAME_PASTE_MENU_SWITCH, () => store.getState().app.framePasteMenuSwitch) export const framePasteMenuSwitchStream = new EpmlStream(FRAME_PASTE_MENU_SWITCH, () => store.getState().app.framePasteMenuSwitch)
export const chatLastSeenStream = new EpmlStream(CHAT_LAST_SEEN, () => store.getState().app.chatLastSeen)
let oldState = { let oldState = {
@ -46,6 +48,9 @@ store.subscribe(() => {
if (oldState.app.framePasteMenuSwitch !== state.app.framePasteMenuSwitch) { if (oldState.app.framePasteMenuSwitch !== state.app.framePasteMenuSwitch) {
framePasteMenuSwitchStream.emit(state.app.framePasteMenuSwitch) framePasteMenuSwitchStream.emit(state.app.framePasteMenuSwitch)
} }
if (oldState.app.chatLastSeen !== state.app.chatLastSeen) {
chatLastSeenStream.emit(state.app.chatLastSeen)
}
if (oldState.app.selectedAddress !== state.app.selectedAddress) { if (oldState.app.selectedAddress !== state.app.selectedAddress) {
selectedAddressStream.emit({ selectedAddressStream.emit({

View File

@ -1,5 +1,5 @@
// Core App Actions here... // Core App Actions here...
import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH } from '../app-action-types.js' import { UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, CHAT_HEADS, ACCOUNT_INFO, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN } from '../app-action-types.js'
export const doUpdateBlockInfo = (blockObj) => { export const doUpdateBlockInfo = (blockObj) => {
return (dispatch, getState) => { return (dispatch, getState) => {
@ -105,3 +105,31 @@ const framePasteMenuSwitch = (payload) => {
payload payload
} }
} }
export const addAutoLoadImageChat = (payload) => {
return {
type: ADD_AUTO_LOAD_IMAGES_CHAT,
payload
}
}
export const removeAutoLoadImageChat = (payload) => {
return {
type: REMOVE_AUTO_LOAD_IMAGES_CHAT,
payload
}
}
export const setChatLastSeen = (payload) => {
return {
type: SET_CHAT_LAST_SEEN,
payload
}
}
export const addChatLastSeen = (payload) => {
return {
type: ADD_CHAT_LAST_SEEN,
payload
}
}

View File

@ -20,3 +20,7 @@ export const ADD_NEW_PLUGIN_URL = 'ADD_NEW_PLUGIN_URL'
export const COPY_MENU_SWITCH = 'COPY_MENU_SWITCH' export const COPY_MENU_SWITCH = 'COPY_MENU_SWITCH'
export const PASTE_MENU_SWITCH = 'PASTE_MENU_SWITCH' export const PASTE_MENU_SWITCH = 'PASTE_MENU_SWITCH'
export const FRAME_PASTE_MENU_SWITCH = 'FRAME_PASTE_MENU_SWITCH' export const FRAME_PASTE_MENU_SWITCH = 'FRAME_PASTE_MENU_SWITCH'
export const ADD_AUTO_LOAD_IMAGES_CHAT = 'ADD_AUTO_LOAD_IMAGES_CHAT'
export const REMOVE_AUTO_LOAD_IMAGES_CHAT = 'REMOVE_AUTO_LOAD_IMAGES_CHAT'
export const SET_CHAT_LAST_SEEN = 'SET_CHAT_LAST_SEEN'
export const ADD_CHAT_LAST_SEEN = 'ADD_CHAT_LAST_SEEN'

View File

@ -1,8 +1,14 @@
// Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage. // Loading state, login state, isNavDrawOpen state etc. None of this needs to be saved to localstorage.
import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH } from './app-action-types.js' import { loadStateFromLocalStorage, saveStateToLocalStorage } from '../../localStorageHelpers.js'
import { LOG_IN, LOG_OUT, NETWORK_CONNECTION_STATUS, INIT_WORKERS, ADD_PLUGIN_URL, ADD_PLUGIN, ADD_NEW_PLUGIN_URL, NAVIGATE, SELECT_ADDRESS, ACCOUNT_INFO, CHAT_HEADS, UPDATE_BLOCK_INFO, UPDATE_NODE_STATUS, UPDATE_NODE_INFO, LOAD_NODE_CONFIG, SET_NODE, ADD_NODE, PAGE_URL, COPY_MENU_SWITCH, PASTE_MENU_SWITCH, FRAME_PASTE_MENU_SWITCH, ADD_AUTO_LOAD_IMAGES_CHAT, REMOVE_AUTO_LOAD_IMAGES_CHAT, SET_CHAT_LAST_SEEN, ADD_CHAT_LAST_SEEN } from './app-action-types.js'
import { initWorkersReducer } from './reducers/init-workers.js' import { initWorkersReducer } from './reducers/init-workers.js'
import { loginReducer } from './reducers/login-reducer.js' import { loginReducer } from './reducers/login-reducer.js'
import { setNode, addNode } from './reducers/manage-node.js' import { setNode, addNode } from './reducers/manage-node.js'
import localForage from "localforage";
const chatLastSeen = localForage.createInstance({
name: "chat-last-seen",
});
const INITIAL_STATE = { const INITIAL_STATE = {
loggedIn: false, loggedIn: false,
@ -42,7 +48,9 @@ const INITIAL_STATE = {
framePasteMenuSwitch: { framePasteMenuSwitch: {
isOpen: false, isOpen: false,
elementId: '' elementId: ''
} },
autoLoadImageChats: loadStateFromLocalStorage('autoLoadImageChats') || [],
chatLastSeen: []
} }
export default (state = INITIAL_STATE, action) => { export default (state = INITIAL_STATE, action) => {
@ -146,6 +154,60 @@ export default (state = INITIAL_STATE, action) => {
...state, ...state,
framePasteMenuSwitch: action.payload framePasteMenuSwitch: action.payload
} }
case ADD_AUTO_LOAD_IMAGES_CHAT: {
const findChat = state.autoLoadImageChats.findIndex((chat)=> chat === action.payload)
console.log({findChat})
if(findChat !== -1) return state
const updatedState = [...state.autoLoadImageChats, action.payload]
saveStateToLocalStorage('autoLoadImageChats', updatedState)
return {
...state,
autoLoadImageChats: updatedState
}
}
case REMOVE_AUTO_LOAD_IMAGES_CHAT: {
const updatedState = state.autoLoadImageChats.filter((chat)=> chat !== action.payload)
saveStateToLocalStorage('autoLoadImageChats', updatedState)
return {
...state,
autoLoadImageChats: updatedState
}
}
case SET_CHAT_LAST_SEEN: {
return {
...state,
chatLastSeen: action.payload
}
}
case ADD_CHAT_LAST_SEEN: {
const chatId = action.payload.key
const timestamp = action.payload.timestamp
if(!chatId || !timestamp) return state
let newChatLastSeen = [...state.chatLastSeen]
const findChatIndex = state.chatLastSeen.findIndex((chat)=> chat.key === chatId)
if(findChatIndex !== -1){
newChatLastSeen[findChatIndex] = {
key: chatId,
timestamp,
}
}
if(findChatIndex === -1){
newChatLastSeen = [...newChatLastSeen, {
key: chatId,
timestamp,
}]
}
chatLastSeen.setItem(chatId, timestamp)
return {
...state,
chatLastSeen: newChatLastSeen
}
}
default: default:
return state return state
} }

View File

@ -9,7 +9,8 @@ html {
--copybutton: #707584; --copybutton: #707584;
--chat-group: #080808; --chat-group: #080808;
--chat-bubble: #9f9f9f0a; --chat-bubble: #9f9f9f0a;
--chat-bubble-bg: #f3f3f3; --chat-bubble-bg: #e6e6e6;
--chat-bubble-myBg: #d1ddf2;
--chat-bubble-msg-color: #080808; --chat-bubble-msg-color: #080808;
--reaction-bubble-outline: #6b6969; --reaction-bubble-outline: #6b6969;
--chat-menu-bg: #ffffff; --chat-menu-bg: #ffffff;
@ -48,6 +49,7 @@ html {
--chatHeadTextActive: #080808; --chatHeadTextActive: #080808;
--group-header: #929292; --group-header: #929292;
--group-drop-shadow: rgb(17 17 26 / 10%) 0px 1px 0px; --group-drop-shadow: rgb(17 17 26 / 10%) 0px 1px 0px;
--reactions-tooltip-bg: #ffffff;
} }
html[theme="dark"] { html[theme="dark"] {
@ -62,6 +64,7 @@ html[theme="dark"] {
--chat-group: #ffffff; --chat-group: #ffffff;
--chat-bubble: #9694941a; --chat-bubble: #9694941a;
--chat-bubble-bg: #2d3749; --chat-bubble-bg: #2d3749;
--chat-bubble-myBg: #40444d;
--chat-bubble-msg-color: #ffffff; --chat-bubble-msg-color: #ffffff;
--reaction-bubble-outline: #ffffff; --reaction-bubble-outline: #ffffff;
--chat-menu-bg: #32394c; --chat-menu-bg: #32394c;
@ -99,5 +102,6 @@ html[theme="dark"] {
--chatHeadText: #ffffff; --chatHeadText: #ffffff;
--chatHeadTextActive: #ffffff; --chatHeadTextActive: #ffffff;
--group-header: #c8c8c8; --group-header: #c8c8c8;
--group-drop-shadow: rgb(191 191 191 / 32%) 0px 1px 0px --group-drop-shadow: rgb(191 191 191 / 32%) 0px 1px 0px;
--reactions-tooltip-bg: #161515;
} }

View File

@ -2,9 +2,8 @@ import { Sha256 } from 'asmcrypto.js'
import Base58 from './api/deps/Base58' import Base58 from './api/deps/Base58'
import { base58PublicKeyToAddress } from './api/wallet/base58PublicKeyToAddress' import { base58PublicKeyToAddress } from './api/wallet/base58PublicKeyToAddress'
import { validateAddress } from './api/wallet/validateAddress' import { validateAddress } from './api/wallet/validateAddress'
import { decryptChatMessage } from './api/transactions/chat/decryptChatMessage'; import { decryptChatMessage } from './api/transactions/chat/decryptChatMessage'
import _ from 'lodash'; import _ from 'lodash'
window.Sha256 = Sha256 window.Sha256 = Sha256
window.Base58 = Base58 window.Base58 = Base58
@ -14,7 +13,6 @@ window.validateAddress = validateAddress
window.decryptChatMessage = decryptChatMessage window.decryptChatMessage = decryptChatMessage
export { initApi, store } from './api_deps.js' export { initApi, store } from './api_deps.js'
export * from './api/deps/deps.js' export * from './api/deps/deps.js'
export * from './api/api.js' export * from './api/api.js'
export * from './api/registerUsername.js' export * from './api/registerUsername.js'

View File

@ -1,7 +1,7 @@
/* /*
Copyright 2017-2018 @ irontiga and vbcs (original developer) Copyright 2017-2018 @ irontiga and vbcs (original developer)
*/ */
'use strict'; 'use strict'
import Base58 from './deps/Base58.js' import Base58 from './deps/Base58.js'
import { Sha256, Sha512 } from 'asmcrypto.js' import { Sha256, Sha512 } from 'asmcrypto.js'
import nacl from './deps/nacl-fast.js' import nacl from './deps/nacl-fast.js'
@ -10,200 +10,200 @@ import utils from './deps/utils.js'
import { generateSaveWalletData } from './storeWallet.js' import { generateSaveWalletData } from './storeWallet.js'
import publicKeyToAddress from './wallet/publicKeyToAddress.js' import publicKeyToAddress from './wallet/publicKeyToAddress.js'
import AltcoinHDWallet from "./bitcoin/AltcoinHDWallet"; import AltcoinHDWallet from "./bitcoin/AltcoinHDWallet"
export default class PhraseWallet { export default class PhraseWallet {
constructor(seed, walletVersion) { constructor(seed, walletVersion) {
this._walletVersion = walletVersion || 2 this._walletVersion = walletVersion || 2
this.seed = seed this.seed = seed
this.savedSeedData = {} this.savedSeedData = {}
this.hasBeenSaved = false this.hasBeenSaved = false
} }
set seed(seed) { set seed(seed) {
this._byteSeed = seed this._byteSeed = seed
this._base58Seed = Base58.encode(seed) this._base58Seed = Base58.encode(seed)
this._addresses = [] this._addresses = []
this.genAddress(0) this.genAddress(0)
} }
getAddress(nonce) { getAddress(nonce) {
return this._addresses[nonce] return this._addresses[nonce]
} }
get addresses() { get addresses() {
return this._addresses return this._addresses
} }
get addressIDs() { get addressIDs() {
return this._addresses.map(addr => { return this._addresses.map(addr => {
return addr.address return addr.address
}) })
} }
get seed() { get seed() {
return this._byteSeed return this._byteSeed
} }
addressExists(nonce) { addressExists(nonce) {
return this._addresses[nonce] != undefined return this._addresses[nonce] != undefined
} }
_genAddressSeed(seed) { _genAddressSeed(seed) {
let newSeed = new Sha512().process(seed).finish().result let newSeed = new Sha512().process(seed).finish().result
newSeed = new Sha512().process(utils.appendBuffer(newSeed, seed)).finish().result newSeed = new Sha512().process(utils.appendBuffer(newSeed, seed)).finish().result
return newSeed return newSeed
} }
genAddress(nonce) { genAddress(nonce) {
if (nonce >= this._addresses.length) { if (nonce >= this._addresses.length) {
this._addresses.length = nonce + 1 this._addresses.length = nonce + 1
} }
if (this.addressExists(nonce)) { if (this.addressExists(nonce)) {
return this.addresses[nonce] return this.addresses[nonce]
} }
const nonceBytes = utils.int32ToBytes(nonce) const nonceBytes = utils.int32ToBytes(nonce)
let addrSeed = new Uint8Array() let addrSeed = new Uint8Array()
addrSeed = utils.appendBuffer(addrSeed, nonceBytes) addrSeed = utils.appendBuffer(addrSeed, nonceBytes)
addrSeed = utils.appendBuffer(addrSeed, this._byteSeed) addrSeed = utils.appendBuffer(addrSeed, this._byteSeed)
addrSeed = utils.appendBuffer(addrSeed, nonceBytes) addrSeed = utils.appendBuffer(addrSeed, nonceBytes)
if (this._walletVersion == 1) { if (this._walletVersion == 1) {
addrSeed = new Sha256().process( addrSeed = new Sha256().process(
new Sha256() new Sha256()
.process(addrSeed) .process(addrSeed)
.finish() .finish()
.result .result
).finish().result ).finish().result
addrSeed = this._byteSeed addrSeed = this._byteSeed
} else { } else {
addrSeed = this._genAddressSeed(addrSeed).slice(0, 32) addrSeed = this._genAddressSeed(addrSeed).slice(0, 32)
} }
const addrKeyPair = nacl.sign.keyPair.fromSeed(new Uint8Array(addrSeed)); const addrKeyPair = nacl.sign.keyPair.fromSeed(new Uint8Array(addrSeed));
const address = publicKeyToAddress(addrKeyPair.publicKey); const address = publicKeyToAddress(addrKeyPair.publicKey);
const qoraAddress = publicKeyToAddress(addrKeyPair.publicKey, true); const qoraAddress = publicKeyToAddress(addrKeyPair.publicKey, true);
// Create Bitcoin HD Wallet // Create Bitcoin HD Wallet
const btcSeed = [...addrSeed]; const btcSeed = [...addrSeed];
const btcWallet = new AltcoinHDWallet({ const btcWallet = new AltcoinHDWallet({
mainnet: { mainnet: {
private: 0x0488ADE4, private: 0x0488ADE4,
public: 0x0488B21E, public: 0x0488B21E,
prefix: 0 prefix: 0
}, },
testnet: { testnet: {
private: 0x04358394, private: 0x04358394,
public: 0x043587CF, public: 0x043587CF,
prefix: 0x6F prefix: 0x6F
} }
}).createWallet(new Uint8Array(btcSeed), false); }).createWallet(new Uint8Array(btcSeed), false);
// Create Litecoin HD Wallet // Create Litecoin HD Wallet
const ltcSeed = [...addrSeed]; const ltcSeed = [...addrSeed];
const ltcWallet = new AltcoinHDWallet({ const ltcWallet = new AltcoinHDWallet({
mainnet: { mainnet: {
private: 0x0488ADE4, private: 0x0488ADE4,
public: 0x0488B21E, public: 0x0488B21E,
prefix: 0x30 prefix: 0x30
}, },
testnet: { testnet: {
private: 0x04358394, private: 0x04358394,
public: 0x043587CF, public: 0x043587CF,
prefix: 0x6F prefix: 0x6F
} }
}).createWallet(new Uint8Array(ltcSeed), false, 'LTC'); }).createWallet(new Uint8Array(ltcSeed), false, 'LTC');
// Create Dogecoin HD Wallet // Create Dogecoin HD Wallet
const dogeSeed = [...addrSeed]; const dogeSeed = [...addrSeed];
const dogeWallet = new AltcoinHDWallet({ const dogeWallet = new AltcoinHDWallet({
mainnet: { mainnet: {
private: 0x02FAC398, private: 0x02FAC398,
public: 0x02FACAFD, public: 0x02FACAFD,
prefix: 0x1E prefix: 0x1E
}, },
testnet: { testnet: {
private: 0x04358394, private: 0x04358394,
public: 0x043587CF, public: 0x043587CF,
prefix: 0x71 prefix: 0x71
} }
}).createWallet(new Uint8Array(dogeSeed), false, 'DOGE'); }).createWallet(new Uint8Array(dogeSeed), false, 'DOGE');
// Create Digibyte HD Wallet // Create Digibyte HD Wallet
const dgbSeed = [...addrSeed]; const dgbSeed = [...addrSeed];
const dgbWallet = new AltcoinHDWallet({ const dgbWallet = new AltcoinHDWallet({
mainnet: { mainnet: {
private: 0x0488ADE4, private: 0x0488ADE4,
public: 0x0488B21E, public: 0x0488B21E,
prefix: 0x1E prefix: 0x1E
}, },
testnet: { testnet: {
private: 0x04358394, private: 0x04358394,
public: 0x043587CF, public: 0x043587CF,
prefix: 0x7E prefix: 0x7E
} }
}).createWallet(new Uint8Array(dgbSeed), false, 'DGB'); }).createWallet(new Uint8Array(dgbSeed), false, 'DGB');
// Create Ravencoin HD Wallet // Create Ravencoin HD Wallet
const rvnSeed = [...addrSeed]; const rvnSeed = [...addrSeed];
const rvnWallet = new AltcoinHDWallet({ const rvnWallet = new AltcoinHDWallet({
mainnet: { mainnet: {
private: 0x0488ADE4, private: 0x0488ADE4,
public: 0x0488B21E, public: 0x0488B21E,
prefix: 0x3C prefix: 0x3C
}, },
testnet: { testnet: {
private: 0x04358394, private: 0x04358394,
public: 0x043587CF, public: 0x043587CF,
prefix: 0x6F prefix: 0x6F
} }
}).createWallet(new Uint8Array(rvnSeed), false, 'RVN'); }).createWallet(new Uint8Array(rvnSeed), false, 'RVN');
// Create Pirate Chain HD Wallet // Create Pirate Chain HD Wallet
const arrrSeed = [...addrSeed]; const arrrSeed = [...addrSeed];
const arrrWallet = new AltcoinHDWallet({ const arrrWallet = new AltcoinHDWallet({
mainnet: { mainnet: {
private: 0x0488ADE4, private: 0x0488ADE4,
public: 0x0488B21E, public: 0x0488B21E,
prefix: [0x16, 0x9A] prefix: [0x16, 0x9A]
}, },
testnet: { testnet: {
private: 0x04358394, private: 0x04358394,
public: 0x043587CF, public: 0x043587CF,
prefix: [0x14, 0x51] prefix: [0x14, 0x51]
} }
}).createWallet(new Uint8Array(arrrSeed), false, 'ARRR'); }).createWallet(new Uint8Array(arrrSeed), false, 'ARRR');
this._addresses[nonce] = { this._addresses[nonce] = {
address, address,
btcWallet, btcWallet,
ltcWallet, ltcWallet,
dogeWallet, dogeWallet,
dgbWallet, dgbWallet,
rvnWallet, rvnWallet,
arrrWallet, arrrWallet,
qoraAddress, qoraAddress,
keyPair: { keyPair: {
publicKey: addrKeyPair.publicKey, publicKey: addrKeyPair.publicKey,
privateKey: addrKeyPair.secretKey privateKey: addrKeyPair.secretKey
}, },
base58PublicKey: Base58.encode(addrKeyPair.publicKey), base58PublicKey: Base58.encode(addrKeyPair.publicKey),
seed: addrSeed, seed: addrSeed,
nonce: nonce nonce: nonce
} }
return this._addresses[nonce] return this._addresses[nonce]
} }
generateSaveWalletData(...args) { generateSaveWalletData(...args) {
return generateSaveWalletData(this, ...args) return generateSaveWalletData(this, ...args)
} }
} }

View File

@ -1,9 +1,5 @@
export { request } from './fetch-request.js' export { request } from './fetch-request.js'
export { transactionTypes as transactions } from './transactions/transactions.js' export { transactionTypes as transactions } from './transactions/transactions.js'
export { processTransaction, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction } from './createTransaction.js' export { processTransaction, createTransaction, computeChatNonce, signChatTransaction, signArbitraryTransaction } from './createTransaction.js'
export { tradeBotCreateRequest, tradeBotRespondRequest, signTradeBotTxn, deleteTradeOffer, sendBtc, sendLtc, sendDoge, sendDgb, sendRvn, sendArrr } from './tradeRequest.js' export { tradeBotCreateRequest, tradeBotRespondRequest, signTradeBotTxn, deleteTradeOffer, sendBtc, sendLtc, sendDoge, sendDgb, sendRvn, sendArrr } from './tradeRequest.js'
export { cancelAllOffers } from './transactions/trade-portal/tradeoffer/cancelAllOffers.js' export { cancelAllOffers } from './transactions/trade-portal/tradeoffer/cancelAllOffers.js'

View File

@ -1,11 +1,10 @@
'use strict'; 'use strict';
import Base58 from '../deps/Base58.js' import Base58 from '../deps/Base58.js'
import { Sha256, Sha512 } from 'asmcrypto.js' import { Sha256, Sha512 } from 'asmcrypto.js'
import jsSHA from "jssha"; import jsSHA from 'jssha'
import RIPEMD160 from '../deps/ripemd160.js' import RIPEMD160 from '../deps/ripemd160.js'
import utils from '../deps/utils.js' import utils from '../deps/utils.js'
import { EllipticCurve, BigInteger } from './ecbn.js'; import { EllipticCurve, BigInteger } from './ecbn.js'
export default class AltcoinHDWallet { export default class AltcoinHDWallet {
@ -101,14 +100,10 @@ export default class AltcoinHDWallet {
this._tmasterPublicKey = '' this._tmasterPublicKey = ''
/** /**
* Child Keys Derivation from the Parent Keys * Child Keys Derivation from the Parent Keys
*/ */
/** /**
* Child Private Key - 32 bytes * Child Private Key - 32 bytes
*/ */
@ -145,13 +140,10 @@ export default class AltcoinHDWallet {
this.xPublicChildKey = '' this.xPublicChildKey = ''
/** /**
* Grand Child Keys Derivation from the Child Keys * Grand Child Keys Derivation from the Child Keys
*/ */
/** /**
* Grand Child Private Key - 32 bytes * Grand Child Private Key - 32 bytes
*/ */
@ -200,7 +192,6 @@ export default class AltcoinHDWallet {
this._tlitecoinLegacyAddress = '' this._tlitecoinLegacyAddress = ''
/** /**
* Wallet - Wallet Object (keys...) * Wallet - Wallet Object (keys...)
*/ */
@ -250,76 +241,69 @@ export default class AltcoinHDWallet {
generateSeedHash(seed, isBIP44, indicator = null) { generateSeedHash(seed, isBIP44, indicator = null) {
let buffer
let buffer;
if (isBIP44) { if (isBIP44) {
buffer = utils.appendBuffer(seed.reverse(), utils.int32ToBytes(indicator)) buffer = utils.appendBuffer(seed.reverse(), utils.int32ToBytes(indicator))
} else { } else {
if(indicator !== null) { if(indicator !== null) {
const indicatorString = utils.stringtoUTF8Array(indicator); const indicatorString = utils.stringtoUTF8Array(indicator)
buffer = utils.appendBuffer(seed.reverse(), indicatorString); buffer = utils.appendBuffer(seed.reverse(), indicatorString)
} }
else else
{ {
buffer = seed.reverse(); buffer = seed.reverse()
} }
} }
const _reverseSeedHash = new Sha256().process(buffer).finish().result; const _reverseSeedHash = new Sha256().process(buffer).finish().result
this.seedHash = new Sha512().process(utils.appendBuffer(seed, _reverseSeedHash)).finish().result; this.seedHash = new Sha512().process(utils.appendBuffer(seed, _reverseSeedHash)).finish().result
} }
generatePrivateKey(seedHash) { generatePrivateKey(seedHash) {
const SECP256K1_CURVE_ORDER = new BigInteger("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141")
const SECP256K1_CURVE_ORDER = new BigInteger("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141"); const privateKeyHash = seedHash.slice(0, 32)
const privateKeyHash = seedHash.slice(0, 32); this.seed58 = Base58.encode(privateKeyHash)
this.seed58 = Base58.encode(privateKeyHash);
const _privateKeyHash = [...privateKeyHash] const _privateKeyHash = [...privateKeyHash]
let privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKeyHash); let privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKeyHash)
const privateKey = (privateKeyBigInt.mod(SECP256K1_CURVE_ORDER.subtract(BigInteger.ONE))).add(BigInteger.ONE) const privateKey = (privateKeyBigInt.mod(SECP256K1_CURVE_ORDER.subtract(BigInteger.ONE))).add(BigInteger.ONE)
this.privateKey = privateKey.toByteArrayUnsigned() this.privateKey = privateKey.toByteArrayUnsigned()
} }
generateChainCode(seedHash) { generateChainCode(seedHash) {
this.chainCode = new Sha256().process(seedHash.slice(32, 64)).finish().result
this.chainCode = new Sha256().process(seedHash.slice(32, 64)).finish().result;
} }
generatePublicKey(privateKey) { generatePublicKey(privateKey) {
const _privateKey = [...privateKey] const _privateKey = [...privateKey]
const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey); const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey)
const epCurve = EllipticCurve.getSECCurveByName("secp256k1"); const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const curvePoints = epCurve.getG().multiply(privateKeyBigInt); const curvePoints = epCurve.getG().multiply(privateKeyBigInt)
const x = curvePoints.getX().toBigInteger(); const x = curvePoints.getX().toBigInteger()
const y = curvePoints.getY().toBigInteger(); const y = curvePoints.getY().toBigInteger()
/** /**
* Deriving Uncompressed Public Key (65 bytes) * Deriving Uncompressed Public Key (65 bytes)
* *
* const publicKeyBytes = EllipticCurve.integerToBytes(x, 32); * const publicKeyBytes = EllipticCurve.integerToBytes(x, 32)
* this.publicKey = publicKeyBytes.concat(EllipticCurve.integerToBytes(y, 32)); * this.publicKey = publicKeyBytes.concat(EllipticCurve.integerToBytes(y, 32))
* this.publicKey.unshift(0x04); // append point indicator * this.publicKey.unshift(0x04) // append point indicator
*/ */
// Compressed Public Key (33 bytes) // Compressed Public Key (33 bytes)
this.publicKey = EllipticCurve.integerToBytes(x, 32) this.publicKey = EllipticCurve.integerToBytes(x, 32)
if (y.isEven()) { if (y.isEven()) {
this.publicKey.unshift(0x02) // append point indicator this.publicKey.unshift(0x02) // append point indicator
} else { } else {
this.publicKey.unshift(0x03) // append point indicator this.publicKey.unshift(0x03) // append point indicator
} }
@ -330,7 +314,6 @@ export default class AltcoinHDWallet {
} }
generateMainnetMasterPrivateKey() { generateMainnetMasterPrivateKey() {
// Serialization Variable // Serialization Variable
const s = [] const s = []
@ -375,7 +358,6 @@ export default class AltcoinHDWallet {
} }
generateMainnetMasterPublicKey() { generateMainnetMasterPublicKey() {
// Serialization Variable // Serialization Variable
const s = [] const s = []
@ -495,19 +477,19 @@ export default class AltcoinHDWallet {
// TODO: Make this more better in the future // TODO: Make this more better in the future
const path = 'm/0/0' const path = 'm/0/0'
// let p = path.split('/'); // let p = path.split('/')
// Get Public kEY // Get Public kEY
const derivePublicChildKey = () => { const derivePublicChildKey = () => {
const _privateKey = [...this.childPrivateKey] const _privateKey = [...this.childPrivateKey]
const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey); const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey)
const epCurve = EllipticCurve.getSECCurveByName("secp256k1"); const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const curvePoints = epCurve.getG().multiply(privateKeyBigInt); const curvePoints = epCurve.getG().multiply(privateKeyBigInt)
const x = curvePoints.getX().toBigInteger(); const x = curvePoints.getX().toBigInteger()
const y = curvePoints.getY().toBigInteger(); const y = curvePoints.getY().toBigInteger()
// Compressed Public Key (33 bytes) // Compressed Public Key (33 bytes)
this.childPublicKey = EllipticCurve.integerToBytes(x, 32) this.childPublicKey = EllipticCurve.integerToBytes(x, 32)
@ -533,15 +515,15 @@ export default class AltcoinHDWallet {
const derivePrivateChildKey = (cI) => { const derivePrivateChildKey = (cI) => {
let ib = []; let ib = []
ib.push((cI >> 24) & 0xff); ib.push((cI >> 24) & 0xff)
ib.push((cI >> 16) & 0xff); ib.push((cI >> 16) & 0xff)
ib.push((cI >> 8) & 0xff); ib.push((cI >> 8) & 0xff)
ib.push(cI & 0xff); ib.push(cI & 0xff)
const s = [...this.publicKey].concat(ib); const s = [...this.publicKey].concat(ib)
const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.chainCode, format: "UINT8ARRAY" } }); const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.chainCode, format: "UINT8ARRAY" } })
_hmacSha512.update(new Uint8Array(s)) _hmacSha512.update(new Uint8Array(s))
@ -550,10 +532,10 @@ export default class AltcoinHDWallet {
// SECP256k1 init // SECP256k1 init
const epCurve = EllipticCurve.getSECCurveByName("secp256k1"); const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.privateKey)).mod(epCurve.getN()); // parse256(IL) + kpar (mod n) ==> ki const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.privateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki
this.childPrivateKey = ki.toByteArrayUnsigned() this.childPrivateKey = ki.toByteArrayUnsigned()
// Call deriveExtendedPrivateChildKey // Call deriveExtendedPrivateChildKey
@ -577,10 +559,10 @@ export default class AltcoinHDWallet {
s.push(...(this.publicKeyHash.slice(0, 4))) s.push(...(this.publicKeyHash.slice(0, 4)))
// Append Child Index // Append Child Index
s.push(childIndex >>> 24); s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff); s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff); s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff); s.push(childIndex & 0xff)
// Append Chain Code // Append Chain Code
s.push(...this.childChainCode) s.push(...this.childChainCode)
@ -619,10 +601,10 @@ export default class AltcoinHDWallet {
s.push(...(this.publicKeyHash.slice(0, 4))) s.push(...(this.publicKeyHash.slice(0, 4)))
// Append Child Index // Append Child Index
s.push(childIndex >>> 24); s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff); s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff); s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff); s.push(childIndex & 0xff)
// Append Chain Code // Append Chain Code
s.push(...this.childChainCode) s.push(...this.childChainCode)
@ -654,24 +636,22 @@ export default class AltcoinHDWallet {
const derivePublicGrandChildKey = () => { const derivePublicGrandChildKey = () => {
const _privateKey = [...this.grandChildPrivateKey] const _privateKey = [...this.grandChildPrivateKey]
const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey); const privateKeyBigInt = BigInteger.fromByteArrayUnsigned(_privateKey)
const epCurve = EllipticCurve.getSECCurveByName("secp256k1"); const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const curvePoints = epCurve.getG().multiply(privateKeyBigInt); const curvePoints = epCurve.getG().multiply(privateKeyBigInt)
const x = curvePoints.getX().toBigInteger(); const x = curvePoints.getX().toBigInteger()
const y = curvePoints.getY().toBigInteger(); const y = curvePoints.getY().toBigInteger()
// Compressed Public Key (33 bytes) // Compressed Public Key (33 bytes)
this.grandChildPublicKey = EllipticCurve.integerToBytes(x, 32) this.grandChildPublicKey = EllipticCurve.integerToBytes(x, 32)
if (y.isEven()) { if (y.isEven()) {
this.grandChildPublicKey.unshift(0x02) // append point indicator this.grandChildPublicKey.unshift(0x02) // append point indicator
} else { } else {
this.grandChildPublicKey.unshift(0x03) // append point indicator this.grandChildPublicKey.unshift(0x03) // append point indicator
} }
@ -729,16 +709,16 @@ export default class AltcoinHDWallet {
const derivePrivateGrandChildKey = (cI, i) => { const derivePrivateGrandChildKey = (cI, i) => {
let ib = []; let ib = []
ib.push((cI >> 24) & 0xff); ib.push((cI >> 24) & 0xff)
ib.push((cI >> 16) & 0xff); ib.push((cI >> 16) & 0xff)
ib.push((cI >> 8) & 0xff); ib.push((cI >> 8) & 0xff)
ib.push(cI & 0xff); ib.push(cI & 0xff)
const s = [...this.childPublicKey].concat(ib); const s = [...this.childPublicKey].concat(ib)
const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.childChainCode, format: "UINT8ARRAY" } }); const _hmacSha512 = new jsSHA("SHA-512", "UINT8ARRAY", { numRounds: 1, hmacKey: { value: this.childChainCode, format: "UINT8ARRAY" } })
_hmacSha512.update(new Uint8Array(s)) _hmacSha512.update(new Uint8Array(s))
@ -746,10 +726,10 @@ export default class AltcoinHDWallet {
this.grandChildChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC this.grandChildChainCode = _hmacSha512.getHMAC('UINT8ARRAY').slice(32, 64) // IR according to the SPEC
// SECP256k1 init // SECP256k1 init
const epCurve = EllipticCurve.getSECCurveByName("secp256k1"); const epCurve = EllipticCurve.getSECCurveByName("secp256k1")
const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.childPrivateKey)).mod(epCurve.getN()); // parse256(IL) + kpar (mod n) ==> ki const ki = IL.add(BigInteger.fromByteArrayUnsigned(this.childPrivateKey)).mod(epCurve.getN()) // parse256(IL) + kpar (mod n) ==> ki
this.grandChildPrivateKey = ki.toByteArrayUnsigned() this.grandChildPrivateKey = ki.toByteArrayUnsigned()
@ -774,10 +754,10 @@ export default class AltcoinHDWallet {
s.push(...(this.childPublicKeyHash.slice(0, 4))) s.push(...(this.childPublicKeyHash.slice(0, 4)))
// Append Child Index // Append Child Index
s.push(childIndex >>> 24); s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff); s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff); s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff); s.push(childIndex & 0xff)
// Append Chain Code // Append Chain Code
s.push(...this.grandChildChainCode) s.push(...this.grandChildChainCode)
@ -816,10 +796,10 @@ export default class AltcoinHDWallet {
s.push(...(this.childPublicKeyHash.slice(0, 4))) s.push(...(this.childPublicKeyHash.slice(0, 4)))
// Append Child Index // Append Child Index
s.push(childIndex >>> 24); s.push(childIndex >>> 24)
s.push((childIndex >>> 16) & 0xff); s.push((childIndex >>> 16) & 0xff)
s.push((childIndex >>> 8) & 0xff); s.push((childIndex >>> 8) & 0xff)
s.push(childIndex & 0xff); s.push(childIndex & 0xff)
// Append Chain Code // Append Chain Code
s.push(...this.grandChildChainCode) s.push(...this.grandChildChainCode)

View File

@ -1,156 +1,154 @@
"use strict"; 'use strict'
// Qortal TX types // Qortal TX types
const TX_TYPES = { const TX_TYPES = {
1: "Genesis", 1: "Genesis",
2: "Payment", 2: "Payment",
3: "Name registration", 3: "Name registration",
4: "Name update", 4: "Name update",
5: "Sell name", 5: "Sell name",
6: "Cancel sell name", 6: "Cancel sell name",
7: "Buy name", 7: "Buy name",
8: "Create poll", 8: "Create poll",
9: "Vote in poll", 9: "Vote in poll",
10: "Arbitrary", 10: "Arbitrary",
11: "Issue asset", 11: "Issue asset",
12: "Transfer asset", 12: "Transfer asset",
13: "Create asset order", 13: "Create asset order",
14: "Cancel asset order", 14: "Cancel asset order",
15: "Multi-payment transaction", 15: "Multi-payment transaction",
16: "Deploy AT", 16: "Deploy AT",
17: "Message", 17: "Message",
18: "Chat", 18: "Chat",
19: "Publicize", 19: "Publicize",
20: "Airdrop", 20: "Airdrop",
21: "AT", 21: "AT",
22: "Create group", 22: "Create group",
23: "Update group", 23: "Update group",
24: "Add group admin", 24: "Add group admin",
25: "Remove group admin", 25: "Remove group admin",
26: "Group ban", 26: "Group ban",
27: "Cancel group ban", 27: "Cancel group ban",
28: "Group kick", 28: "Group kick",
29: "Group invite", 29: "Group invite",
30: "Cancel group invite", 30: "Cancel group invite",
31: "Join group", 31: "Join group",
32: "Leave group", 32: "Leave group",
33: "Group approval", 33: "Group approval",
34: "Set group", 34: "Set group",
35: "Update asset", 35: "Update asset",
36: "Account flags", 36: "Account flags",
37: "Enable forging", 37: "Enable forging",
38: "Reward share", 38: "Reward share",
39: "Account level", 39: "Account level",
40: "Transfer privs", 40: "Transfer privs",
41: "Presence" 41: "Presence"
} }
// Qortal error codes // Qortal error codes
const ERROR_CODES = { const ERROR_CODES = {
1: "Valid OK", 1: "Valid OK",
2: "Invalid address", 2: "Invalid address",
3: "Negative amount", 3: "Negative amount",
4: "Nagative fee", 4: "Nagative fee",
5: "No balance", 5: "No balance",
6: "Invalid reference", 6: "Invalid reference",
7: "Invalid time length", 7: "Invalid time length",
8: "Invalid value length", 8: "Invalid value length",
9: "Name already registered", 9: "Name already registered",
10: "Name does not exist", 10: "Name does not exist",
11: "Invalid name owner", 11: "Invalid name owner",
12: "Name already for sale", 12: "Name already for sale",
13: "Name not for sale", 13: "Name not for sale",
14: "Name buyer already owner", 14: "Name buyer already owner",
15: "Invalid amount", 15: "Invalid amount",
16: "Invalid seller", 16: "Invalid seller",
17: "Name not lowercase", 17: "Name not lowercase",
18: "Invalid description length", 18: "Invalid description length",
19: "Invalid options length", 19: "Invalid options length",
20: "Invalid option length", 20: "Invalid option length",
21: "Duplicate option", 21: "Duplicate option",
22: "Poll already created", 22: "Poll already created",
23: "Poll already has votes", 23: "Poll already has votes",
24: "Poll does not exist", 24: "Poll does not exist",
25: "Option does not exist", 25: "Option does not exist",
26: "Already voted for that option", 26: "Already voted for that option",
27: "Invalid data length", 27: "Invalid data length",
28: "Invalid quantity", 28: "Invalid quantity",
29: "Asset does not exist", 29: "Asset does not exist",
30: "Invalid return", 30: "Invalid return",
31: "Have equals want", 31: "Have equals want",
32: "Order does not exist", 32: "Order does not exist",
33: "Invalid order creator", 33: "Invalid order creator",
34: "Invalid payments length", 34: "Invalid payments length",
35: "Negative price", 35: "Negative price",
36: "Invalid creation bytes", 36: "Invalid creation bytes",
37: "Invalid tags length", 37: "Invalid tags length",
38: "Invalid type length", 38: "Invalid type length",
39: "Invalid AT transaction", 39: "Invalid AT transaction",
40: "Insufficient fee", 40: "Insufficient fee",
41: "Asset does not match AT", 41: "Asset does not match AT",
43: "Asset already exists", 43: "Asset already exists",
44: "Missing creator", 44: "Missing creator",
45: "Timestamp too old", 45: "Timestamp too old",
46: "Timestamp too new", 46: "Timestamp too new",
47: "Too many unconfirmed", 47: "Too many unconfirmed",
48: "Group already exists", 48: "Group already exists",
49: "Group does not exist", 49: "Group does not exist",
50: "Invalid group owner", 50: "Invalid group owner",
51: "Already group memeber", 51: "Already group memeber",
52: "Group owner can not leave", 52: "Group owner can not leave",
53: "Not group member", 53: "Not group member",
54: "Already group admin", 54: "Already group admin",
55: "Not group admin", 55: "Not group admin",
56: "Invalid lifetime", 56: "Invalid lifetime",
57: "Invite unknown", 57: "Invite unknown",
58: "Ban exists", 58: "Ban exists",
59: "Ban unknown", 59: "Ban unknown",
60: "Banned from group", 60: "Banned from group",
61: "Join request", 61: "Join request",
62: "Invalid group approval threshold", 62: "Invalid group approval threshold",
63: "Group ID mismatch", 63: "Group ID mismatch",
64: "Invalid group ID", 64: "Invalid group ID",
65: "Transaction unknown", 65: "Transaction unknown",
66: "Transaction already confirmed", 66: "Transaction already confirmed",
67: "Invalid TX group", 67: "Invalid TX group",
68: "TX group ID mismatch", 68: "TX group ID mismatch",
69: "Multiple names forbidden", 69: "Multiple names forbidden",
70: "Invalid asset owner", 70: "Invalid asset owner",
71: "AT is finished", 71: "AT is finished",
72: "No flag permission", 72: "No flag permission",
73: "Not minting accout", 73: "Not minting accout",
77: "Invalid rewardshare percent", 77: "Invalid rewardshare percent",
78: "Public key unknown", 78: "Public key unknown",
79: "Invalid public key", 79: "Invalid public key",
80: "AT unknown", 80: "AT unknown",
81: "AT already exists", 81: "AT already exists",
82: "Group approval not required", 82: "Group approval not required",
83: "Group approval decided", 83: "Group approval decided",
84: "Maximum reward shares", 84: "Maximum reward shares",
85: "Transaction already exists", 85: "Transaction already exists",
86: "No blockchain lock", 86: "No blockchain lock",
87: "Order already closed", 87: "Order already closed",
88: "Clock not synced", 88: "Clock not synced",
89: "Asset not spendable", 89: "Asset not spendable",
90: "Account can not reward share", 90: "Account can not reward share",
91: "Self share exists", 91: "Self share exists",
92: "Account already exists", 92: "Account already exists",
93: "Invalid group block delay", 93: "Invalid group block delay",
94: "Incorrect nonce", 94: "Incorrect nonce",
95: "Ivalid timestamp signature", 95: "Ivalid timestamp signature",
96: "Address blocked", 96: "Address blocked",
97: "Name Blocked", 97: "Name Blocked",
98: "Group approval required", 98: "Group approval required",
99: "Account not transferable", 99: "Account not transferable",
999: "Ivalid but ok", 999: "Ivalid but ok",
1000: "Not yet released." 1000: "Not yet released."
} }
const CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP = 0
// Qortal 8 decimals // Qortal 8 decimals
const QORT_DECIMALS = 1e8 const QORT_DECIMALS = 1e8
@ -160,6 +158,9 @@ const ADDRESS_VERSION = 58
// Proxy for api calls // Proxy for api calls
const PROXY_URL = "/proxy/" const PROXY_URL = "/proxy/"
// Chat reference timestamp
const CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP = 1674316800000
// Used as a salt for all qora addresses. Salts used for storing your private keys in local storage will be randomly generated // Used as a salt for all qora addresses. Salts used for storing your private keys in local storage will be randomly generated
const STATIC_SALT = new Uint8Array([54, 190, 201, 206, 65, 29, 123, 129, 147, 231, 180, 166, 171, 45, 95, 165, 78, 200, 208, 194, 44, 207, 221, 146, 45, 238, 68, 68, 69, 102, 62, 6]) const STATIC_SALT = new Uint8Array([54, 190, 201, 206, 65, 29, 123, 129, 147, 231, 180, 166, 171, 45, 95, 165, 78, 200, 208, 194, 44, 207, 221, 146, 45, 238, 68, 68, 69, 102, 62, 6])
const BCRYPT_ROUNDS = 10 // Remember that the total work spent on key derivation is BCRYPT_ROUNDS * KDF_THREADS const BCRYPT_ROUNDS = 10 // Remember that the total work spent on key derivation is BCRYPT_ROUNDS * KDF_THREADS

View File

@ -6,33 +6,33 @@ import signArbitrary from './transactions/arbitrary/signArbitrary.js'
export const createTransaction = (type, keyPair, params) => { export const createTransaction = (type, keyPair, params) => {
const tx = new transactions[type]() const tx = new transactions[type]()
tx.keyPair = keyPair tx.keyPair = keyPair
Object.keys(params).forEach(param => { Object.keys(params).forEach(param => {
tx[param] = params[param] tx[param] = params[param]
}) })
return tx return tx
} }
// Compute Chat Nonce // Compute Chat Nonce
export const computeChatNonce = bytes => request('/chat/compute', { export const computeChatNonce = bytes => request('/chat/compute', {
method: 'POST', method: 'POST',
body: Base58.encode(bytes) body: Base58.encode(bytes)
}) })
// Sign Chat Transactions // Sign Chat Transactions
export const signChatTransaction = (chatBytes, nonce, keyPair) => { export const signChatTransaction = (chatBytes, nonce, keyPair) => {
return signChat(chatBytes, nonce, keyPair) return signChat(chatBytes, nonce, keyPair)
} }
// Sign Arbitrary Transactions // Sign Arbitrary Transactions
export const signArbitraryTransaction = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) => { export const signArbitraryTransaction = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) => {
return signArbitrary(arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) return signArbitrary(arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair)
} }
// Process Transactions // Process Transactions
export const processTransaction = bytes => request('/transactions/process', { export const processTransaction = bytes => request('/transactions/process', {
method: 'POST', method: 'POST',
body: Base58.encode(bytes) body: Base58.encode(bytes)
}) })

View File

@ -4,26 +4,26 @@ import Base58 from './deps/Base58.js'
import { decryptStoredWallet } from './decryptStoredWallet.js' import { decryptStoredWallet } from './decryptStoredWallet.js'
export const createWallet = async (sourceType, source, statusUpdateFn) => { export const createWallet = async (sourceType, source, statusUpdateFn) => {
let version, seed let version, seed
switch (sourceType) { switch (sourceType) {
case 'phrase': case 'phrase':
version = 2 version = 2
seed = await kdf(source.seedPhrase, void 0, statusUpdateFn) seed = await kdf(source.seedPhrase, void 0, statusUpdateFn)
break break
case 'seed': case 'seed':
version = 1 version = 1
seed = Base58.decode(source.seed) seed = Base58.decode(source.seed)
break break
case 'storedWallet': case 'storedWallet':
case 'backedUpSeed': case 'backedUpSeed':
version = source.wallet.version version = source.wallet.version
seed = await decryptStoredWallet(source.password, source.wallet, statusUpdateFn) seed = await decryptStoredWallet(source.password, source.wallet, statusUpdateFn)
break break
default: default:
throw 'sourceType ' + sourceType + ' not recognized' throw 'sourceType ' + sourceType + ' not recognized'
} }
const wallet = new PhraseWallet(seed, version) const wallet = new PhraseWallet(seed, version)
return wallet return wallet
} }

View File

@ -3,21 +3,21 @@ import { kdf } from './kdf.js'
import { HmacSha512, AES_CBC } from 'asmcrypto.js' import { HmacSha512, AES_CBC } from 'asmcrypto.js'
export const decryptStoredWallet = async (password, wallet, statusFn = () => { }) => { export const decryptStoredWallet = async (password, wallet, statusFn = () => { }) => {
statusFn('Decoding saved data') statusFn('Decoding saved data')
const encryptedSeedBytes = Base58.decode(wallet.encryptedSeed) const encryptedSeedBytes = Base58.decode(wallet.encryptedSeed)
const iv = Base58.decode(wallet.iv) const iv = Base58.decode(wallet.iv)
const salt = Base58.decode(wallet.salt) const salt = Base58.decode(wallet.salt)
statusFn('Generating decryption key') statusFn('Generating decryption key')
const key = await kdf(password, salt, statusFn) const key = await kdf(password, salt, statusFn)
const encryptionKey = key.slice(0, 32) const encryptionKey = key.slice(0, 32)
const macKey = key.slice(32, 63) const macKey = key.slice(32, 63)
statusFn('Checking key') statusFn('Checking key')
const mac = new HmacSha512(macKey).process(encryptedSeedBytes).finish().result const mac = new HmacSha512(macKey).process(encryptedSeedBytes).finish().result
if (Base58.encode(mac) !== wallet.mac) { if (Base58.encode(mac) !== wallet.mac) {
throw new Error('Incorrect password') throw new Error('Incorrect password')
} }
statusFn('Decrypting') statusFn('Decrypting')
const decryptedBytes = AES_CBC.decrypt(encryptedSeedBytes, encryptionKey, false, iv) const decryptedBytes = AES_CBC.decrypt(encryptedSeedBytes, encryptionKey, false, iv)
return decryptedBytes return decryptedBytes
} }

View File

@ -4,36 +4,36 @@ import { Sha512 } from 'asmcrypto.js'
import utils from '../api/deps/utils.js' import utils from '../api/deps/utils.js'
export const kdf = async (seed, salt, status = () => { }) => { export const kdf = async (seed, salt, status = () => { }) => {
const state = store.getState() const state = store.getState()
const config = state.config const config = state.config
const workers = state.app.workers.workers const workers = state.app.workers.workers
status('Waiting for workers to be ready') status('Waiting for workers to be ready')
await stateAwait(state => state.app.workers.ready) await stateAwait(state => state.app.workers.ready)
status('Deriving key parts') status('Deriving key parts')
salt = new Uint8Array(salt) salt = new Uint8Array(salt)
const seedParts = await Promise.all(workers.map((worker, index) => { const seedParts = await Promise.all(workers.map((worker, index) => {
const nonce = index const nonce = index
return worker.request('kdf', { return worker.request('kdf', {
key: seed, key: seed,
salt, salt,
nonce, nonce,
staticSalt: config.crypto.staticSalt, staticSalt: config.crypto.staticSalt,
staticBcryptSalt: config.crypto.staticBcryptSalt staticBcryptSalt: config.crypto.staticBcryptSalt
}).then(data => { }).then(data => {
let jsonData let jsonData
try { try {
jsonData = JSON.parse(data) jsonData = JSON.parse(data)
data = jsonData data = jsonData
} catch (e) { } catch (e) {
// ... // ...
} }
if (seed !== data.key) throw new Error('Error, incorrect key. ' + seed + ' !== ' + data.key) if (seed !== data.key) throw new Error('Error, incorrect key. ' + seed + ' !== ' + data.key)
if (nonce !== data.nonce) throw new Error('Error, incorrect nonce') if (nonce !== data.nonce) throw new Error('Error, incorrect nonce')
return data.result return data.result
}) })
})) }))
status('Combining key parts') status('Combining key parts')
const result = new Sha512().process(utils.stringtoUTF8Array(config.crypto.staticSalt + seedParts.reduce((a, c) => a + c))).finish().result const result = new Sha512().process(utils.stringtoUTF8Array(config.crypto.staticSalt + seedParts.reduce((a, c) => a + c))).finish().result
status('Key is ready ') status('Key is ready ')
return result return result
} }

View File

@ -8,39 +8,32 @@ const CHECK_LAST_REF_INTERVAL = 30 * 1000 // err 30 seconds
const pendingAddresses = {} const pendingAddresses = {}
// const config = store.getState().config
// const node = config.coin.node.api
// const baseUrl = node.url + node.tail
const checkLastRefs = () => { const checkLastRefs = () => {
Object.entries(pendingAddresses).forEach(([address, fn]) => { Object.entries(pendingAddresses).forEach(([address, fn]) => {
// console.log(fn, address) request('addresses/lastreference/' + address).then(res => {
request('addresses/lastreference/' + address).then(res => { if (res === 'false') return
if (res === 'false') return fn(res)
fn(res) delete pendingAddresses[address]
delete pendingAddresses[address] clearInterval(lastRefInterval)
clearInterval(lastRefInterval) })
}) })
// fetch(baseUrl + 'addresses/lastreference/' + address)
// .then(async res => res.text())
})
} }
const lastRefInterval = setInterval(() => checkLastRefs(), CHECK_LAST_REF_INTERVAL) const lastRefInterval = setInterval(() => checkLastRefs(), CHECK_LAST_REF_INTERVAL)
const callOnLastRef = (address, fn) => { const callOnLastRef = (address, fn) => {
pendingAddresses[address] = fn pendingAddresses[address] = fn
} }
export const registerUsername = async ({ name, address, lastRef, keyPair }) => { export const registerUsername = async ({ name, address, lastRef, keyPair }) => {
callOnLastRef(address, lastreference => { callOnLastRef(address, lastreference => {
const txBytes = createTransaction(TX_TYPE, keyPair, { const txBytes = createTransaction(TX_TYPE, keyPair, {
registrantPublicKey: keyPair.publicKey, registrantPublicKey: keyPair.publicKey,
registrantAddress: address, registrantAddress: address,
name, name,
value: address, value: address,
lastReference: lastreference lastReference: lastreference
}) })
processTransaction(txBytes).then(res => {}) processTransaction(txBytes).then(res => { })
}) })
} }

View File

@ -1,33 +1,29 @@
import { HmacSha512, AES_CBC } from 'asmcrypto.js' import { HmacSha512, AES_CBC } from 'asmcrypto.js'
import { kdf } from './kdf.js' import { kdf } from './kdf.js'
// import Base58 from '../qora/deps/Base58.js'
import Base58 from './deps/Base58.js' import Base58 from './deps/Base58.js'
const getRandomValues = window.crypto ? window.crypto.getRandomValues.bind(window.crypto) : window.msCrypto.getRandomValues.bind(window.msCrypto) const getRandomValues = window.crypto ? window.crypto.getRandomValues.bind(window.crypto) : window.msCrypto.getRandomValues.bind(window.msCrypto)
export const generateSaveWalletData = async (wallet, password, kdfThreads, statusUpdateFn) => { export const generateSaveWalletData = async (wallet, password, kdfThreads, statusUpdateFn) => {
statusUpdateFn('Generating random values') statusUpdateFn('Generating random values')
let iv = new Uint8Array(16) let iv = new Uint8Array(16)
getRandomValues(iv) getRandomValues(iv)
let salt = new Uint8Array(32) let salt = new Uint8Array(32)
getRandomValues(salt) // Can actually use a salt this time, as we can store the salt with the wallet getRandomValues(salt)
const key = await kdf(password, salt, statusUpdateFn)
// const key = PBKDF2_HMAC_SHA512.bytes(utils.stringtoUTF8Array(password), salt, PBKDF2_ROUNDS, 64) // 512bit key to be split in two for mac/encryption statusUpdateFn('Encrypting seed')
const key = await kdf(password, salt, statusUpdateFn) const encryptionKey = key.slice(0, 32)
statusUpdateFn('Encrypting seed') const macKey = key.slice(32, 63)
const encryptionKey = key.slice(0, 32) const encryptedSeed = AES_CBC.encrypt(wallet._byteSeed, encryptionKey, false, iv)
const macKey = key.slice(32, 63) statusUpdateFn('Generating mac')
const encryptedSeed = AES_CBC.encrypt(wallet._byteSeed, encryptionKey, false, iv) const mac = new HmacSha512(macKey).process(encryptedSeed).finish().result
// const mac = HmacSha512.bytes(encryptedSeed, macKey) return {
statusUpdateFn('Generating mac') address0: wallet._addresses[0].address,
const mac = new HmacSha512(macKey).process(encryptedSeed).finish().result encryptedSeed: Base58.encode(encryptedSeed),
return { salt: Base58.encode(salt),
address0: wallet._addresses[0].address, iv: Base58.encode(iv),
encryptedSeed: Base58.encode(encryptedSeed), version: wallet._walletVersion,
salt: Base58.encode(salt), mac: Base58.encode(mac),
iv: Base58.encode(iv), kdfThreads
version: wallet._walletVersion, }
mac: Base58.encode(mac),
kdfThreads
}
} }

View File

@ -1,145 +1,140 @@
// Trade Bot // Trade Bot
import TradeBotCreateRequest from './transactions/trade-portal/tradebot/TradeBotCreateRequest.js'; import TradeBotCreateRequest from './transactions/trade-portal/tradebot/TradeBotCreateRequest.js'
import TradeBotRespondRequest from './transactions/trade-portal/tradebot/TradeBotRespondRequest.js'; import TradeBotRespondRequest from './transactions/trade-portal/tradebot/TradeBotRespondRequest.js'
import signTradeBotTransaction from './transactions/trade-portal/tradebot/signTradeBotTransaction.js' import signTradeBotTransaction from './transactions/trade-portal/tradebot/signTradeBotTransaction.js'
import DeleteTradeOffer from './transactions/trade-portal/tradeoffer/DeleteTradeOffer.js'
// Trade Offer
import DeleteTradeOffer from './transactions/trade-portal/tradeoffer/DeleteTradeOffer.js';
import { request } from './fetch-request' import { request } from './fetch-request'
// TradeBotCreateRequest // TradeBotCreateRequest
export const tradeBotCreateRequest = (requestObject) => { export const tradeBotCreateRequest = (requestObject) => {
const txn = new TradeBotCreateRequest().createTransaction(requestObject) const txn = new TradeBotCreateRequest().createTransaction(requestObject)
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/tradebot/create?apiKey=${myNode.apiKey}`, { return request(`/crosschain/tradebot/create?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'text/plain', 'Accept': 'text/plain',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(txn) body: JSON.stringify(txn)
}) })
} }
// TradeBotRespondRequest // TradeBotRespondRequest
export const tradeBotRespondRequest = (requestObject) => { export const tradeBotRespondRequest = (requestObject) => {
const txn = new TradeBotRespondRequest().createTransaction(requestObject) const txn = new TradeBotRespondRequest().createTransaction(requestObject)
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/tradebot/respond?apiKey=${myNode.apiKey}`, { return request(`/crosschain/tradebot/respond?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(txn) body: JSON.stringify(txn)
}) })
} }
// Sign Trade Transactions // Sign Trade Transactions
export const signTradeBotTxn = (unsignedTxn, keyPair) => { export const signTradeBotTxn = (unsignedTxn, keyPair) => {
return signTradeBotTransaction(unsignedTxn, keyPair) return signTradeBotTransaction(unsignedTxn, keyPair)
} }
// Delete Trade Offer // Delete Trade Offer
export const deleteTradeOffer = (requestObject) => { export const deleteTradeOffer = (requestObject) => {
const txn = new DeleteTradeOffer().createTransaction(requestObject) const txn = new DeleteTradeOffer().createTransaction(requestObject)
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/tradeoffer?apiKey=${myNode.apiKey}`, { return request(`/crosschain/tradeoffer?apiKey=${myNode.apiKey}`, {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(txn) body: JSON.stringify(txn)
}) })
} }
// Send BTC // Send BTC
export const sendBtc = (requestObject) => { export const sendBtc = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/btc/send?apiKey=${myNode.apiKey}`, { return request(`/crosschain/btc/send?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(requestObject) body: JSON.stringify(requestObject)
}) })
} }
// Send LTC // Send LTC
export const sendLtc = (requestObject) => { export const sendLtc = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/ltc/send?apiKey=${myNode.apiKey}`, { return request(`/crosschain/ltc/send?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(requestObject) body: JSON.stringify(requestObject)
}) })
} }
// Send DOGE // Send DOGE
export const sendDoge = (requestObject) => { export const sendDoge = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/doge/send?apiKey=${myNode.apiKey}`, { return request(`/crosschain/doge/send?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(requestObject) body: JSON.stringify(requestObject)
}) })
} }
// Send DGB // Send DGB
export const sendDgb = (requestObject) => { export const sendDgb = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/dgb/send?apiKey=${myNode.apiKey}`, { return request(`/crosschain/dgb/send?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(requestObject) body: JSON.stringify(requestObject)
}) })
} }
// Send RVN // Send RVN
export const sendRvn = (requestObject) => { export const sendRvn = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/rvn/send?apiKey=${myNode.apiKey}`, { return request(`/crosschain/rvn/send?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(requestObject) body: JSON.stringify(requestObject)
}) })
} }
// Send ARRR // Send ARRR
export const sendArrr = (requestObject) => { export const sendArrr = (requestObject) => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]; const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
return request(`/crosschain/arrr/send?apiKey=${myNode.apiKey}`, { return request(`/crosschain/arrr/send?apiKey=${myNode.apiKey}`, {
method: 'POST', method: 'POST',
headers: { headers: {
'Accept': 'application/json', 'Accept': 'application/json',
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify(requestObject) body: JSON.stringify(requestObject)
}) })
} }

View File

@ -1,50 +1,35 @@
'use strict'; 'use strict'
import TransactionBase from './TransactionBase.js' import TransactionBase from './TransactionBase.js'
import { QORT_DECIMALS } from '../constants.js' import { QORT_DECIMALS } from '../constants.js'
// import { Sha256 } from 'asmcrypto.js/dist_es5/entry-export_all.js'
export default class PaymentTransaction extends TransactionBase { export default class PaymentTransaction extends TransactionBase {
constructor () { constructor() {
super() super()
this.type = 20 this.type = 20
this.amount = 42 * Math.pow(10, 8) }
this.tests.push(
() => {
if (!(this._amount >= 0)) {
return 'Invalid amount ' + this._amount / QORT_DECIMALS
}
return true
},
() => {
if (!(this._recipient instanceof Uint8Array && this._recipient.length == 25)) {
return 'Invalid recipient ' + Base58.encode(this._recipient)
}
return true
}
)
}
set recipient (recipient) { // Always Base58 encoded. Accepts Uint8Array or Base58 string. set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
} }
set amount (amount) {
this._amount = amount * QORT_DECIMALS
this._amountBytes = this.constructor.utils.int64ToBytes(amount)
}
set reference (seed) { set amount(amount) {
const sha = seed => new Sha512().process(seed).finish().result this._amount = amount * QORT_DECIMALS
let reference = sha(sha(seed)) this._amountBytes = this.constructor.utils.int64ToBytes(amount)
reference += reference }
}
get params () { set reference(seed) {
const params = super.params const sha = seed => new Sha512().process(seed).finish().result
params.push( let reference = sha(sha(seed))
this._recipient, reference += reference
this._amountBytes, }
this._feeBytes
) get params() {
return params const params = super.params
} params.push(
this._recipient,
this._amountBytes,
this._feeBytes
)
return params
}
} }

View File

@ -1,31 +1,22 @@
'use strict'; 'use strict'
import TransactionBase from './TransactionBase.js' import TransactionBase from './TransactionBase.js'
// import { QORT_DECIMALS } from "../constants.js" // Not needed, no amount
export default class DelegationTransaction extends TransactionBase { export default class DelegationTransaction extends TransactionBase {
constructor () { constructor() {
super() super()
this.type = 18 this.type = 18
this.tests.push( }
() => {
if (!(this._superNodeAddress instanceof Uint8Array && this._superNodeAddress.length == 25)) {
return 'Invalid recipient ' + Base58.encode(this._superNodeAddress)
}
return true
}
)
}
set superNodeAddress (superNodeAddress) { // Always Base58 encoded. Accepts Uint8Array or Base58 string. set superNodeAddress(superNodeAddress) {
this._superNodeAddress = superNodeAddress instanceof Uint8Array ? superNodeAddress : this.constructor.Base58.decode(superNodeAddress) this._superNodeAddress = superNodeAddress instanceof Uint8Array ? superNodeAddress : this.constructor.Base58.decode(superNodeAddress)
} }
get params () { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._superNodeAddress, this._superNodeAddress,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,95 +1,47 @@
"use strict"; 'use strict'
import PaymentTransaction from "./PaymentTransaction.js" import PaymentTransaction from './PaymentTransaction.js'
import { QORT_DECIMALS } from "../constants.js" import { QORT_DECIMALS } from '../constants.js'
/* ==================================== export default class MessageTransaction extends PaymentTransaction {
EXTEND THE PAYMENT TRANSACTION YOU CLOWN constructor() {
====================================== */ super()
this.type = 17
this._key = this.constructor.utils.int64ToBytes(0);
this._isEncrypted = new Uint8Array(1); // Defaults to false
this._isText = new Uint8Array(1); // Defaults to false
}
export default class MessageTransaction extends PaymentTransaction{ set message(message /* UTF8 String */) {
constructor(){ // ...yes? no?
super(); this.messageText = message
this.type = 17
this._key = this.constructor.utils.int64ToBytes(0); // Not sure about encoding here...
this._isEncrypted = new Uint8Array(1); // Defaults to false this._message = this.constructor.utils.stringtoUTF8Array(message)
this._isText = new Uint8Array(1); // Defaults to false this._messageLength = this.constructor.utils.int64ToBytes(this._message.length)
} }
set message(message /* UTF8 String */){ set isEncrypted(isEncrypted) {
// ...yes? no? this._isEncrypted[0] = isEncrypted
this.messageText = message; }
// Not sure about encoding here... set isText(isText) {
//this._message = message instanceof Uint8Array ? message : this.constructor.Base58.decode(message); this._isText[0] = isText
this._message = this.constructor.utils.stringtoUTF8Array(message) }
this._messageLength = this.constructor.utils.int64ToBytes(this._message.length)
} get _params() {
set isEncrypted(isEncrypted){ return [
this._isEncrypted[0] = isEncrypted; this._typeBytes,
} this._timestampBytes,
set isText(isText){ this._lastReference,
this._isText[0] = isText; this._keyPair.publicKey,
} this._recipient,
get _params(){ this._key,
// dont extend super because paymentTrasaction is different this._amountBytes,
//const params = super.params; this._messageLength,
return [ this._message,
this._typeBytes, this._isEncrypted,
this._timestampBytes, this._isText,
this._lastReference, this._feeBytes
this._keyPair.publicKey, ]
this._recipient, }
this._key,
this._amountBytes,
this._messageLength,
this._message,
this._isEncrypted,
this._isText,
this._feeBytes
]
}
} }
//"use strict";
//function generateSignatureMessageTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted) => {
// const data = generateMessageTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted);
// return nacl.sign.detached(data, keyPair.privateKey);
//}
//
//function generateMessageTransaction(keyPair, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted, signature) => {
// return appendBuffer(generateMessageTransactionBase(keyPair.publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted),
// signature);
//}
//function generateMessageTransactionBase(publicKey, lastReference, recipient, amount, fee, timestamp, message, isText, isEncrypted) => {
// txType = TYPES.MESSAGE_TRANSACTION;
//
// const typeBytes = int32ToBytes(txType);
// const timestampBytes = int64ToBytes(timestamp);
// const amountBytes = int64ToBytes(amount * 100000000);
// const feeBytes = int64ToBytes(fee * 100000000);
// const messageLength = int32ToBytes(message.length);
// const key = int64ToBytes(0);
//
// isTextB = new Uint8Array(1);
// isTextB[0] = isText;
//
// isEncryptedB = new Uint8Array(1);
// isEncryptedB[0] = isEncrypted;
//
// let data = new Uint8Array();
//
// data = appendBuffer(data, typeBytes);
// data = appendBuffer(data, timestampBytes);
// data = appendBuffer(data, lastReference);
// data = appendBuffer(data, publicKey);
// data = appendBuffer(data, recipient);
// data = appendBuffer(data, key);
// data = appendBuffer(data, amountBytes);
// data = appendBuffer(data, messageLength);
// data = appendBuffer(data, message);
// data = appendBuffer(data, isEncryptedB);
// data = appendBuffer(data, isTextB);
// data = appendBuffer(data, feeBytes);
//
// return data;
//}

View File

@ -1,80 +1,63 @@
'use strict'; 'use strict'
import TransactionBase from './TransactionBase.js' import TransactionBase from './TransactionBase.js'
import Base58 from '../deps/Base58.js' import Base58 from '../deps/Base58.js'
import { store } from '../../api.js' import { store } from '../../api.js'
export default class PaymentTransaction extends TransactionBase { export default class PaymentTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 2 this.type = 2
this.tests.push( }
() => {
if (!(this._amount >= 0)) {
return 'Invalid amount ' + this._amount / store.getState().config.coin.decimals
}
return true
},
() => {
if (!(this._recipient instanceof Uint8Array && this._recipient.length == 25)) {
return 'Invalid recipient ' + Base58.encode(this._recipient)
}
return true
}
)
}
set recipient(recipient) { // Always Base58 encoded. Accepts Uint8Array or Base58 string. render(html) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) const conf = store.getState().config
} return html`
<table>
<tr>
<th>${this._dialogto}:</th>
</tr>
<tr>
<td>${this.dialogAddress} ${' '}-</td>
<td>${Base58.encode(this._recipient)}</td>
</tr>
${this.recipientName ? html`
<tr>
<td>${this.dialogName} ${' '}-</td>
<td>${this.recipientName}</td>
</tr>
` : ''}
<tr>
<th>${this._dialogamount}</th>
<td>${this._amount / conf.coin.decimals} ${conf.coin.symbol}</td>
</tr>
</table>
`
}
set dialogto(dialogto) { set recipient(recipient) {
this._dialogto = dialogto this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
} }
set dialogamount(dialogamount) { set dialogto(dialogto) {
this._dialogamount = dialogamount this._dialogto = dialogto
} }
set amount(amount) {
this._amount = Math.round(amount * store.getState().config.coin.decimals)
this._amountBytes = this.constructor.utils.int64ToBytes(this._amount)
}
get params() { set dialogamount(dialogamount) {
const params = super.params this._dialogamount = dialogamount
params.push( }
this._recipient,
this._amountBytes,
this._feeBytes
)
return params
}
render(html) { set amount(amount) {
const conf = store.getState().config this._amount = Math.round(amount * store.getState().config.coin.decimals)
return html` this._amountBytes = this.constructor.utils.int64ToBytes(this._amount)
<table> }
<tr>
<th>${this._dialogto}:</th> get params() {
const params = super.params
</tr> params.push(
<tr> this._recipient,
<td>${this.dialogAddress} ${' '}-</td> this._amountBytes,
<td>${Base58.encode(this._recipient)}</td> this._feeBytes
)
</tr> return params
${this.recipientName ? html` }
<tr>
<td>${this.dialogName} ${' '}-</td>
<td>${this.recipientName}</td>
</tr>
` : ''}
<tr>
<th>${this._dialogamount}</th>
<td>${this._amount / conf.coin.decimals} ${conf.coin.symbol}</td>
</tr>
</table>
`
}
} }

View File

@ -3,11 +3,11 @@ import ChatBase from "./chat/ChatBase.js"
import { QORT_DECIMALS } from "../constants.js" import { QORT_DECIMALS } from "../constants.js"
export default class PublicizeTransaction extends ChatBase { export default class PublicizeTransaction extends ChatBase {
constructor() { constructor() {
super(); super()
this.type = 19 this.type = 19
this.fee = 0 this.fee = 0
} }
set proofOfWorkNonce(proofOfWorkNonce) { set proofOfWorkNonce(proofOfWorkNonce) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce) this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce)

View File

@ -1,166 +1,168 @@
'use strict'; 'use strict'
import { TX_TYPES, QORT_DECIMALS } from '../constants.js' import { TX_TYPES, QORT_DECIMALS } from '../constants.js'
import nacl from '../deps/nacl-fast.js' import nacl from '../deps/nacl-fast.js'
import Base58 from '../deps/Base58.js' import Base58 from '../deps/Base58.js'
import utils from '../deps/utils.js' import utils from '../deps/utils.js'
export default class TransactionBase { export default class TransactionBase {
static get utils() { static get utils() {
return utils return utils
} }
static get nacl() { static get nacl() {
return nacl return nacl
} }
static get Base58() { static get Base58() {
return Base58 return Base58
} }
constructor() { constructor() {
// Defaults this.fee = 0
this.fee = 0 this.groupID = 0
this.groupID = 0 this.timestamp = Date.now()
this.timestamp = Date.now() this.tests = [
this.tests = [ () => {
() => { if (!(this._type >= 1 && this._type in TX_TYPES)) {
if (!(this._type >= 1 && this._type in TX_TYPES)) { return 'Invalid type: ' + this.type
return 'Invalid type: ' + this.type }
} return true
return true },
}, () => {
() => { if (this._fee < 0) {
if (this._fee < 0) { return 'Invalid fee: ' + this._fee / QORT_DECIMALS
return 'Invalid fee: ' + this._fee / QORT_DECIMALS }
} return true
return true },
}, () => {
() => { if (this._groupID < 0 || !Number.isInteger(this._groupID)) {
if (this._groupID < 0 || !Number.isInteger(this._groupID)) { return 'Invalid groupID: ' + this._groupID
return 'Invalid groupID: ' + this._groupID }
} return true
return true },
}, () => {
() => { if (!(new Date(this._timestamp)).getTime() > 0) {
if (!(new Date(this._timestamp)).getTime() > 0) { return 'Invalid timestamp: ' + this._timestamp
return 'Invalid timestamp: ' + this._timestamp }
} return true
return true },
}, () => {
() => { if (!(this._lastReference instanceof Uint8Array && this._lastReference.byteLength == 64)) {
if (!(this._lastReference instanceof Uint8Array && this._lastReference.byteLength == 64)) { if (this._lastReference == 0) {
if (this._lastReference == 0) { return 'Invalid last reference. Please ensure that you have at least 0.001 QORT for the transaction fee.'
// No prior transactions exist }
return 'Invalid last reference. Please ensure that you have at least 0.001 QORT for the transaction fee.' return 'Invalid last reference: ' + this._lastReference
} }
return 'Invalid last reference: ' + this._lastReference return true
} },
return true () => {
}, if (!(this._keyPair)) {
() => { return 'keyPair must be specified'
if (!(this._keyPair)) { }
return 'keyPair must be specified' if (!(this._keyPair.publicKey instanceof Uint8Array && this._keyPair.publicKey.byteLength === 32)) {
} return 'Invalid publicKey'
if (!(this._keyPair.publicKey instanceof Uint8Array && this._keyPair.publicKey.byteLength === 32)) { }
return 'Invalid publicKey' if (!(this._keyPair.privateKey instanceof Uint8Array && this._keyPair.privateKey.byteLength === 64)) {
} return 'Invalid privateKey'
if (!(this._keyPair.privateKey instanceof Uint8Array && this._keyPair.privateKey.byteLength === 64)) { }
return 'Invalid privateKey' return true
} }
return true ]
} }
]
}
set keyPair(keyPair) { render(html) {
this._keyPair = keyPair return html`render method to display requested transaction info`
} }
set type(type) {
this.typeText = TX_TYPES[type]
this._type = type
this._typeBytes = this.constructor.utils.int32ToBytes(this._type)
}
set groupID(groupID) {
this._groupID = groupID
this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID)
}
set timestamp(timestamp) {
this._timestamp = timestamp
this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp)
}
set fee(fee) {
this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
set lastReference(lastReference) { // Always Base58 encoded. Accepts Uint8Array or Base58 string.
// lastReference could be a string or an Uint8Array
this._lastReference = lastReference instanceof Uint8Array ? lastReference : this.constructor.Base58.decode(lastReference)
}
get params() {
return [
this._typeBytes,
this._timestampBytes,
this._groupIDBytes,
this._lastReference,
this._keyPair.publicKey
]
}
get signedBytes() {
if (!this._signedBytes) {
this.sign()
}
return this._signedBytes
}
// render function but NOT lit element set keyPair(keyPair) {
render(html) { this._keyPair = keyPair
return html`render method to display requested transaction info` }
}
validParams() { set type(type) {
let finalResult = { this.typeText = TX_TYPES[type]
valid: true this._type = type
} this._typeBytes = this.constructor.utils.int32ToBytes(this._type)
// const valid = }
this.tests.some(test => {
const result = test()
if (result !== true) {
finalResult = {
valid: false,
message: result
}
return true // exists the loop
}
})
return finalResult
}
generateBase() { set groupID(groupID) {
const isValid = this.validParams() this._groupID = groupID
if (!isValid.valid) { this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID)
throw new Error(isValid.message) }
}
let result = new Uint8Array()
this.params.forEach(item => { set timestamp(timestamp) {
result = this.constructor.utils.appendBuffer(result, item) this._timestamp = timestamp
}) this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp)
}
this._base = result set fee(fee) {
return result this._fee = fee * QORT_DECIMALS
} this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
}
sign() { set lastReference(lastReference) {
if (!this._keyPair) { this._lastReference = lastReference instanceof Uint8Array ? lastReference : this.constructor.Base58.decode(lastReference)
throw new Error('keyPair not defined') }
}
if (!this._base) { get params() {
this.generateBase() return [
} this._typeBytes,
this._timestampBytes,
this._groupIDBytes,
this._lastReference,
this._keyPair.publicKey
]
}
this._signature = this.constructor.nacl.sign.detached(this._base, this._keyPair.privateKey) get signedBytes() {
if (!this._signedBytes) {
this.sign()
}
return this._signedBytes
}
this._signedBytes = this.constructor.utils.appendBuffer(this._base, this._signature) validParams() {
let finalResult = {
valid: true
}
this.tests.some(test => {
const result = test()
if (result !== true) {
finalResult = {
valid: false,
message: result
}
return true // exists the loop
}
})
return finalResult
}
return this._signature generateBase() {
} const isValid = this.validParams()
if (!isValid.valid) {
throw new Error(isValid.message)
}
let result = new Uint8Array()
this.params.forEach(item => {
result = this.constructor.utils.appendBuffer(result, item)
})
this._base = result
return result
}
sign() {
if (!this._keyPair) {
throw new Error('keyPair not defined')
}
if (!this._base) {
this.generateBase()
}
this._signature = this.constructor.nacl.sign.detached(this._base, this._keyPair.privateKey)
this._signedBytes = this.constructor.utils.appendBuffer(this._base, this._signature)
return this._signature
}
} }

View File

@ -1,42 +1,42 @@
'use strict'; 'use strict'
import TransactionBase from './TransactionBase.js' import TransactionBase from './TransactionBase.js'
import Base58 from '../deps/Base58.js' import Base58 from '../deps/Base58.js'
import { store } from '../../api.js' import { store } from '../../api.js'
import { QORT_DECIMALS } from '../constants.js' import { QORT_DECIMALS } from '../constants.js'
export default class TransferPrivsTransaction extends TransactionBase { export default class TransferPrivsTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 40 this.type = 40
} }
render(html) { render(html) {
const conf = store.getState().config const conf = store.getState().config
return html` return html`
Are you sure to transfer privileges to this account ? Are you sure to transfer privileges to this account ?
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
On pressing confirm, the transfer privileges request will be sent! On pressing confirm, the transfer privileges request will be sent!
` `
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._recipient, this._recipient,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -2,38 +2,37 @@ import nacl from '../../deps/nacl-fast.js'
import utils from '../../deps/utils.js' import utils from '../../deps/utils.js'
import Base58 from '../../deps/Base58.js' import Base58 from '../../deps/Base58.js'
const signArbitrary = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) => { const signArbitrary = (arbitraryBytesBase58, arbitraryBytesForSigningBase58, nonce, keyPair) => {
if (!arbitraryBytesBase58) { if (!arbitraryBytesBase58) {
throw new Error('ArbitraryBytesBase58 not defined') throw new Error('ArbitraryBytesBase58 not defined')
} }
if (!nonce) { if (!nonce) {
throw new Error('Nonce not defined') throw new Error('Nonce not defined')
} }
if (!keyPair) { if (!keyPair) {
throw new Error('keyPair not defined') throw new Error('keyPair not defined')
} }
const arbitraryBytes = Base58.decode(arbitraryBytesBase58) const arbitraryBytes = Base58.decode(arbitraryBytesBase58)
const _arbitraryBytesBuffer = Object.keys(arbitraryBytes).map(function (key) { return arbitraryBytes[key]; }); const _arbitraryBytesBuffer = Object.keys(arbitraryBytes).map(function (key) { return arbitraryBytes[key]; })
const arbitraryBytesBuffer = new Uint8Array(_arbitraryBytesBuffer) const arbitraryBytesBuffer = new Uint8Array(_arbitraryBytesBuffer)
const arbitraryBytesForSigning = Base58.decode(arbitraryBytesForSigningBase58) const arbitraryBytesForSigning = Base58.decode(arbitraryBytesForSigningBase58)
const _arbitraryBytesForSigningBuffer = Object.keys(arbitraryBytesForSigning).map(function (key) { return arbitraryBytesForSigning[key]; }); const _arbitraryBytesForSigningBuffer = Object.keys(arbitraryBytesForSigning).map(function (key) { return arbitraryBytesForSigning[key]; })
const arbitraryBytesForSigningBuffer = new Uint8Array(_arbitraryBytesForSigningBuffer) const arbitraryBytesForSigningBuffer = new Uint8Array(_arbitraryBytesForSigningBuffer)
const _nonce = utils.int32ToBytes(nonce) const _nonce = utils.int32ToBytes(nonce)
arbitraryBytesBuffer.set(_nonce, 112) arbitraryBytesBuffer.set(_nonce, 112)
arbitraryBytesForSigningBuffer.set(_nonce, 112) arbitraryBytesForSigningBuffer.set(_nonce, 112)
const signature = nacl.sign.detached(arbitraryBytesForSigningBuffer, keyPair.privateKey) const signature = nacl.sign.detached(arbitraryBytesForSigningBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(arbitraryBytesBuffer, signature) const signedBytes = utils.appendBuffer(arbitraryBytesBuffer, signature)
return signedBytes return signedBytes
} }
export default signArbitrary export default signArbitrary

View File

@ -1,42 +1,37 @@
"use strict"; 'use strict'
/*
TO DO
*/
(function () {
function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) => {
const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp)
return nacl.sign.detached(data, keyPair.privateKey)
}
(function(){ function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) => {
function generateSignatureArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp) => { return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp), signature)
const data = generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp); }
return nacl.sign.detached(data, keyPair.privateKey);
}
function generateArbitraryTransactionV3(keyPair, lastReference, service, arbitraryData, fee, timestamp, signature) => { function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) => {
return appendBuffer(generateArbitraryTransactionV3Base(keyPair.publicKey, lastReference, service, arbitraryData, fee, timestamp), const txType = TYPES.ARBITRARY_TRANSACTION
signature); const typeBytes = int32ToBytes(txType)
} const timestampBytes = int64ToBytes(timestamp)
const feeBytes = int64ToBytes(fee * 100000000)
const serviceBytes = int32ToBytes(service)
const dataSizeBytes = int32ToBytes(arbitraryData.length)
const paymentsLengthBytes = int32ToBytes(0) // Support payments - not yet.
function generateArbitraryTransactionV3Base(publicKey, lastReference, service, arbitraryData, fee, timestamp) => { var data = new Uint8Array()
const txType = TYPES.ARBITRARY_TRANSACTION;
const typeBytes = int32ToBytes(txType);
const timestampBytes = int64ToBytes(timestamp);
const feeBytes = int64ToBytes(fee * 100000000);
const serviceBytes = int32ToBytes(service);
const dataSizeBytes = int32ToBytes(arbitraryData.length);
const paymentsLengthBytes = int32ToBytes(0); // Support payments - not yet.
var data = new Uint8Array(); data = appendBuffer(data, typeBytes)
data = appendBuffer(data, timestampBytes)
data = appendBuffer(data, lastReference)
data = appendBuffer(data, publicKey)
data = appendBuffer(data, paymentsLengthBytes)
// Here it is necessary to insert the payments, if there are
data = appendBuffer(data, serviceBytes)
data = appendBuffer(data, dataSizeBytes)
data = appendBuffer(data, arbitraryData)
data = appendBuffer(data, feeBytes)
data = appendBuffer(data, typeBytes); return data
data = appendBuffer(data, timestampBytes); }
data = appendBuffer(data, lastReference); }())
data = appendBuffer(data, publicKey);
data = appendBuffer(data, paymentsLengthBytes);
// Here it is necessary to insert the payments, if there are
data = appendBuffer(data, serviceBytes);
data = appendBuffer(data, dataSizeBytes);
data = appendBuffer(data, arbitraryData);
data = appendBuffer(data, feeBytes);
return data;
}
}())

View File

@ -1,4 +1,4 @@
'use strict'; 'use strict'
import { TX_TYPES, QORT_DECIMALS } from '../../constants.js' import { TX_TYPES, QORT_DECIMALS } from '../../constants.js'
import nacl from '../../deps/nacl-fast.js' import nacl from '../../deps/nacl-fast.js'
import Base58 from '../../deps/Base58.js' import Base58 from '../../deps/Base58.js'
@ -67,28 +67,33 @@ export default class ChatBase {
set keyPair(keyPair) { set keyPair(keyPair) {
this._keyPair = keyPair this._keyPair = keyPair
} }
set type(type) { set type(type) {
this.typeText = TX_TYPES[type] this.typeText = TX_TYPES[type]
this._type = type this._type = type
this._typeBytes = this.constructor.utils.int32ToBytes(this._type) this._typeBytes = this.constructor.utils.int32ToBytes(this._type)
} }
set groupID(groupID) { set groupID(groupID) {
this._groupID = groupID this._groupID = groupID
this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID) this._groupIDBytes = this.constructor.utils.int32ToBytes(this._groupID)
} }
set timestamp(timestamp) { set timestamp(timestamp) {
this._timestamp = timestamp this._timestamp = timestamp
this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp) this._timestampBytes = this.constructor.utils.int64ToBytes(this._timestamp)
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set lastReference(lastReference) { set lastReference(lastReference) {
this._lastReference = lastReference instanceof Uint8Array ? lastReference : this.constructor.Base58.decode(lastReference) this._lastReference = lastReference instanceof Uint8Array ? lastReference : this.constructor.Base58.decode(lastReference)
} }
get params() {
get params() {
return [ return [
this._typeBytes, this._typeBytes,
this._timestampBytes, this._timestampBytes,
@ -99,7 +104,6 @@ export default class ChatBase {
} }
get chatBytes() { get chatBytes() {
const isValid = this.validParams() const isValid = this.validParams()
if (!isValid.valid) { if (!isValid.valid) {
throw new Error(isValid.message) throw new Error(isValid.message)

View File

@ -1,4 +1,4 @@
"use strict"; 'use strict'
import ChatBase from "./ChatBase.js" import ChatBase from "./ChatBase.js"
import nacl from '../../deps/nacl-fast.js' import nacl from '../../deps/nacl-fast.js'
import ed2curve from '../../deps/ed2curve.js' import ed2curve from '../../deps/ed2curve.js'
@ -7,92 +7,86 @@ import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants.js'
export default class ChatTransaction extends ChatBase { export default class ChatTransaction extends ChatBase {
constructor() { constructor() {
super(); super()
this.type = 18 this.type = 18
this.fee = 0 this.fee = 0
} }
set recipientPublicKey(recipientPublicKey) { set recipientPublicKey(recipientPublicKey) {
this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey
this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey) this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey)
}
} set proofOfWorkNonce(proofOfWorkNonce) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce)
}
set proofOfWorkNonce(proofOfWorkNonce) { set recipient(recipient) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
} this._hasReceipient = new Uint8Array(1)
this._hasReceipient[0] = 1
}
set hasChatReference(hasChatReference) {
this._hasChatReference = new Uint8Array(1)
this._hasChatReference[0] = hasChatReference
}
set recipient(recipient) { set chatReference(chatReference) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._chatReference = chatReference instanceof Uint8Array ? chatReference : this.constructor.Base58.decode(chatReference)
this._hasReceipient = new Uint8Array(1) }
this._hasReceipient[0] = 1
}
set hasChatReference(hasChatReference) { set message(message) {
this._hasChatReference = new Uint8Array(1) this.messageText = message;
this._hasChatReference[0] = hasChatReference this._message = this.constructor.utils.stringtoUTF8Array(message)
} this._messageLength = this.constructor.utils.int32ToBytes(this._message.length)
}
set chatReference(chatReference) { set isEncrypted(isEncrypted) {
this._chatReference = chatReference instanceof Uint8Array ? chatReference : this.constructor.Base58.decode(chatReference) this._isEncrypted = new Uint8Array(1)
} this._isEncrypted[0] = isEncrypted
set message(message) { if (isEncrypted === 1) {
const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey)
const sharedSecret = new Uint8Array(32)
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
this.messageText = message; this._chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
this._encryptedMessage = nacl.secretbox(this._message, this._lastReference.slice(0, 24), this._chatEncryptionSeed)
}
this._message = this.constructor.utils.stringtoUTF8Array(message) this._myMessage = isEncrypted === 1 ? this._encryptedMessage : this._message
this._messageLength = this.constructor.utils.int32ToBytes(this._message.length) this._myMessageLenth = isEncrypted === 1 ? this.constructor.utils.int32ToBytes(this._myMessage.length) : this._messageLength
} }
set isEncrypted(isEncrypted) { set isText(isText) {
this._isEncrypted = new Uint8Array(1); this._isText = new Uint8Array(1)
this._isEncrypted[0] = isEncrypted; this._isText[0] = isText
}
if (isEncrypted === 1) { get params() {
const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey) const params = super.params
const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey) params.push(
const sharedSecret = new Uint8Array(32); this._proofOfWorkNonce,
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey); this._hasReceipient,
this._recipient,
this._myMessageLenth,
this._myMessage,
this._isEncrypted,
this._isText,
this._feeBytes
)
this._chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result // After the feature trigger timestamp we need to include chat reference
this._encryptedMessage = nacl.secretbox(this._message, this._lastReference.slice(0, 24), this._chatEncryptionSeed) if (new Date(this._timestamp).getTime() >= CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP) {
} params.push(this._hasChatReference)
this._myMessage = isEncrypted === 1 ? this._encryptedMessage : this._message if (this._hasChatReference[0] == 1) {
this._myMessageLenth = isEncrypted === 1 ? this.constructor.utils.int32ToBytes(this._myMessage.length) : this._messageLength params.push(this._chatReference)
} }
}
set isText(isText) { return params
this._isText = new Uint8Array(1); }
this._isText[0] = isText;
}
get params() {
const params = super.params;
params.push(
this._proofOfWorkNonce,
this._hasReceipient,
this._recipient,
this._myMessageLenth,
this._myMessage,
this._isEncrypted,
this._isText,
this._feeBytes
)
console.log('updated test')
// After the feature trigger timestamp we need to include chat reference
if (new Date(this._timestamp).getTime() >= CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP) {
params.push(this._hasChatReference)
if (this._hasChatReference[0] == 1) {
console.log('past through', this._chatReference)
params.push(this._chatReference)
}
}
console.log({params})
return params;
}
} }

View File

@ -1,72 +1,68 @@
"use strict"; 'use strict'
import ChatBase from "./ChatBase.js" import ChatBase from "./ChatBase.js"
import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants.js' import { CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP } from '../../constants.js'
export default class GroupChatTransaction extends ChatBase { export default class GroupChatTransaction extends ChatBase {
constructor() { constructor() {
super(); super();
this.type = 18 this.type = 18
this.fee = 0 this.fee = 0
} }
set proofOfWorkNonce(proofOfWorkNonce) { set proofOfWorkNonce(proofOfWorkNonce) {
this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce) this._proofOfWorkNonce = this.constructor.utils.int32ToBytes(proofOfWorkNonce)
} }
set hasReceipient(hasReceipient) {
this._hasReceipient = new Uint8Array(1)
this._hasReceipient[0] = hasReceipient
}
set hasReceipient(hasReceipient) { set message(message) {
this._hasReceipient = new Uint8Array(1) this.messageText = message
this._hasReceipient[0] = hasReceipient this._message = this.constructor.utils.stringtoUTF8Array(message)
} this._messageLength = this.constructor.utils.int32ToBytes(this._message.length)
}
set hasChatReference(hasChatReference) { set hasChatReference(hasChatReference) {
this._hasChatReference = new Uint8Array(1) this._hasChatReference = new Uint8Array(1)
this._hasChatReference[0] = hasChatReference this._hasChatReference[0] = hasChatReference
} }
set chatReference(chatReference) { set chatReference(chatReference) {
this._chatReference = chatReference instanceof Uint8Array ? chatReference : this.constructor.Base58.decode(chatReference) this._chatReference = chatReference instanceof Uint8Array ? chatReference : this.constructor.Base58.decode(chatReference)
} }
set message(message) { set isEncrypted(isEncrypted) {
this._isEncrypted = new Uint8Array(1);
this._isEncrypted[0] = isEncrypted
}
this.messageText = message; set isText(isText) {
this._isText = new Uint8Array(1)
this._isText[0] = isText
}
this._message = this.constructor.utils.stringtoUTF8Array(message) get params() {
this._messageLength = this.constructor.utils.int32ToBytes(this._message.length) const params = super.params
} params.push(
this._proofOfWorkNonce,
this._hasReceipient,
this._messageLength,
this._message,
this._isEncrypted,
this._isText,
this._feeBytes
)
set isEncrypted(isEncrypted) { // After the feature trigger timestamp we need to include chat reference
this._isEncrypted = new Uint8Array(1); if (new Date(this._timestamp).getTime() >= CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP) {
this._isEncrypted[0] = isEncrypted; // Set to false... params.push(this._hasChatReference)
}
set isText(isText) { if (this._hasChatReference[0] == 1) {
this._isText = new Uint8Array(1); params.push(this._chatReference)
this._isText[0] = isText; // Set to true }
} }
return params
get params() { }
const params = super.params;
params.push(
this._proofOfWorkNonce,
this._hasReceipient,
this._messageLength,
this._message,
this._isEncrypted,
this._isText,
this._feeBytes
)
// After the feature trigger timestamp we need to include chat reference
if (new Date(this._timestamp).getTime() >= CHAT_REFERENCE_FEATURE_TRIGGER_TIMESTAMP) {
params.push(this._hasChatReference)
if (this._hasChatReference[0] == 1) {
params.push(this._chatReference)
}
}
return params;
}
} }

View File

@ -3,25 +3,24 @@ import Base58 from '../../deps/Base58.js'
import ed2curve from '../../deps/ed2curve.js' import ed2curve from '../../deps/ed2curve.js'
import { Sha256 } from 'asmcrypto.js' import { Sha256 } from 'asmcrypto.js'
export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => { export const decryptChatMessage = (encryptedMessage, privateKey, recipientPublicKey, lastReference) => {
let _encryptedMessage = Base58.decode(encryptedMessage) let _encryptedMessage = Base58.decode(encryptedMessage)
const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey const _base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? Base58.encode(recipientPublicKey) : recipientPublicKey
const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey) const _recipientPublicKey = Base58.decode(_base58RecipientPublicKey)
const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference) const _lastReference = lastReference instanceof Uint8Array ? lastReference : Base58.decode(lastReference)
const convertedPrivateKey = ed2curve.convertSecretKey(privateKey) const convertedPrivateKey = ed2curve.convertSecretKey(privateKey)
const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey) const convertedPublicKey = ed2curve.convertPublicKey(_recipientPublicKey)
const sharedSecret = new Uint8Array(32); const sharedSecret = new Uint8Array(32);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey); nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey)
const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result const _chatEncryptionSeed = new Sha256().process(sharedSecret).finish().result
const _decryptedMessage = nacl.secretbox.open(_encryptedMessage, _lastReference.slice(0, 24), _chatEncryptionSeed) const _decryptedMessage = nacl.secretbox.open(_encryptedMessage, _lastReference.slice(0, 24), _chatEncryptionSeed)
let decryptedMessage = '' let decryptedMessage = ''
_decryptedMessage === false ? decryptedMessage : decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage); _decryptedMessage === false ? decryptedMessage : decryptedMessage = new TextDecoder('utf-8').decode(_decryptedMessage)
return decryptedMessage return decryptedMessage
} }

View File

@ -1,46 +1,43 @@
import nacl from '../../deps/nacl-fast.js' import nacl from '../../deps/nacl-fast.js'
import utils from '../../deps/utils.js' import utils from '../../deps/utils.js'
const signChat = (chatBytes, nonce, keyPair) => { const signChat = (chatBytes, nonce, keyPair) => {
if (!chatBytes) { if (!chatBytes) {
throw new Error('Chat Bytes not defined') throw new Error('Chat Bytes not defined')
} }
if (!nonce) { if (!nonce) {
throw new Error('Nonce not defined') throw new Error('Nonce not defined')
} }
if (!keyPair) { if (!keyPair) {
throw new Error('keyPair not defined') throw new Error('keyPair not defined')
} }
const _nonce = utils.int32ToBytes(nonce) const _nonce = utils.int32ToBytes(nonce)
if (chatBytes.length === undefined) { if (chatBytes.length === undefined) {
const _chatBytesBuffer = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; }); const _chatBytesBuffer = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; })
const chatBytesBuffer = new Uint8Array(_chatBytesBuffer) const chatBytesBuffer = new Uint8Array(_chatBytesBuffer)
chatBytesBuffer.set(_nonce, 112) chatBytesBuffer.set(_nonce, 112)
const signature = nacl.sign.detached(chatBytesBuffer, keyPair.privateKey)
const signature = nacl.sign.detached(chatBytesBuffer, keyPair.privateKey) const signedBytes = utils.appendBuffer(chatBytesBuffer, signature)
const signedBytes = utils.appendBuffer(chatBytesBuffer, signature) return signedBytes
} else {
const chatBytesBuffer = new Uint8Array(chatBytes)
chatBytesBuffer.set(_nonce, 112)
return signedBytes const signature = nacl.sign.detached(chatBytesBuffer, keyPair.privateKey)
} else {
const chatBytesBuffer = new Uint8Array(chatBytes)
chatBytesBuffer.set(_nonce, 112)
const signedBytes = utils.appendBuffer(chatBytesBuffer, signature)
const signature = nacl.sign.detached(chatBytesBuffer, keyPair.privateKey) return signedBytes
}
const signedBytes = utils.appendBuffer(chatBytesBuffer, signature)
return signedBytes
}
} }
export default signChat export default signChat

View File

@ -1,53 +1,53 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class AddGroupAdminTransaction extends TransactionBase { export default class AddGroupAdminTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 24 this.type = 24
} }
render(html) { render(html) {
return html` return html`
${this._addAdminDialog1} ${this._addAdminDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._addAdminDialog2} ${this._addAdminDialog2}
` `
} }
set addAdminDialog1(addAdminDialog1) { set addAdminDialog1(addAdminDialog1) {
this._addAdminDialog1 = addAdminDialog1 this._addAdminDialog1 = addAdminDialog1
} }
set addAdminDialog2(addAdminDialog2) { set addAdminDialog2(addAdminDialog2) {
this._addAdminDialog2 = addAdminDialog2 this._addAdminDialog2 = addAdminDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,53 +1,53 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class CancelGroupBanTransaction extends TransactionBase { export default class CancelGroupBanTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 27 this.type = 27
} }
render(html) { render(html) {
return html` return html`
${this._cancelBanMemberDialog1} ${this._cancelBanMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._cancelBanMemberDialog2} ${this._cancelBanMemberDialog2}
` `
} }
set cancelBanMemberDialog1(cancelBanMemberDialog1) { set cancelBanMemberDialog1(cancelBanMemberDialog1) {
this._cancelBanMemberDialog1= cancelBanMemberDialog1 this._cancelBanMemberDialog1 = cancelBanMemberDialog1
} }
set cancelBanMemberDialog2(cancelBanMemberDialog2) { set cancelBanMemberDialog2(cancelBanMemberDialog2) {
this._cancelBanMemberDialog2 = cancelBanMemberDialog2 this._cancelBanMemberDialog2 = cancelBanMemberDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,60 +1,60 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class CancelGroupInviteTransaction extends TransactionBase { export default class CancelGroupInviteTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 30 this.type = 30
} }
render(html) { render(html) {
return html` return html`
${this._cancelInviteDialog1} ${this._cancelInviteDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._memberName}</span> <span style="color: #000;">${this._memberName}</span>
</div> </div>
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._cancelInviteDialog2} ${this._cancelInviteDialog2}
` `
} }
set memberName(memberName) { set memberName(memberName) {
this._memberName = memberName this._memberName = memberName
} }
set cancelInviteDialog1(cancelInviteDialog1) { set cancelInviteDialog1(cancelInviteDialog1) {
this._cancelInviteDialog1 = cancelInviteDialog1 this._cancelInviteDialog1 = cancelInviteDialog1
} }
set cancelInviteDialog2(cancelInviteDialog2) { set cancelInviteDialog2(cancelInviteDialog2) {
this._cancelInviteDialog2 = cancelInviteDialog2 this._cancelInviteDialog2 = cancelInviteDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,98 +1,98 @@
"use strict"; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class CreateGroupTransaction extends TransactionBase { export default class CreateGroupTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 22 this.type = 22
} }
render(html) { render(html) {
return html` return html`
${this._groupdialog5} ${this._groupdialog5}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<div>${this._groupdialog7}: <span style="color: #000;">${this._rGroupName}</span></div> <div>${this._groupdialog7}: <span style="color: #000;">${this._rGroupName}</span></div>
<br> <br>
<div>${this._groupdialog8}: <span style="color: #000;">${this._rGroupDesc}</span></div> <div>${this._groupdialog8}: <span style="color: #000;">${this._rGroupDesc}</span></div>
<br> <br>
<div>${this._groupdialog9}: <span style="color: #000;">${this.myGroupType === 1 ? "Public" : "Private"}</span></div> <div>${this._groupdialog9}: <span style="color: #000;">${this.myGroupType === 1 ? "Public" : "Private"}</span></div>
</div> </div>
${this._groupdialog6} ${this._groupdialog6}
` `
} }
set groupdialog5(groupdialog5) { set groupdialog5(groupdialog5) {
this._groupdialog5 = groupdialog5 this._groupdialog5 = groupdialog5
} }
set groupdialog6(groupdialog6) { set groupdialog6(groupdialog6) {
this._groupdialog6 = groupdialog6 this._groupdialog6 = groupdialog6
} }
set groupdialog7(groupdialog7) { set groupdialog7(groupdialog7) {
this._groupdialog7 = groupdialog7 this._groupdialog7 = groupdialog7
} }
set groupdialog8(groupdialog8) { set groupdialog8(groupdialog8) {
this._groupdialog8 = groupdialog8 this._groupdialog8 = groupdialog8
} }
set groupdialog9(groupdialog9) { set groupdialog9(groupdialog9) {
this._groupdialog9 = groupdialog9 this._groupdialog9 = groupdialog9
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set rGroupName(rGroupName) { set rGroupName(rGroupName) {
this._rGroupName = rGroupName; this._rGroupName = rGroupName
this._rGroupNameBytes = this.constructor.utils.stringtoUTF8Array(this._rGroupName.toLocaleLowerCase()) this._rGroupNameBytes = this.constructor.utils.stringtoUTF8Array(this._rGroupName.toLocaleLowerCase())
this._rGroupNameLength = this.constructor.utils.int32ToBytes(this._rGroupNameBytes.length) this._rGroupNameLength = this.constructor.utils.int32ToBytes(this._rGroupNameBytes.length)
} }
set rGroupDesc(rGroupDesc) { set rGroupDesc(rGroupDesc) {
this._rGroupDesc = rGroupDesc; this._rGroupDesc = rGroupDesc
this._rGroupDescBytes = this.constructor.utils.stringtoUTF8Array(this._rGroupDesc.toLocaleLowerCase()) this._rGroupDescBytes = this.constructor.utils.stringtoUTF8Array(this._rGroupDesc.toLocaleLowerCase())
this._rGroupDescLength = this.constructor.utils.int32ToBytes(this._rGroupDescBytes.length) this._rGroupDescLength = this.constructor.utils.int32ToBytes(this._rGroupDescBytes.length)
} }
set rGroupType(rGroupType) { set rGroupType(rGroupType) {
this.myGroupType = rGroupType; this.myGroupType = rGroupType
this._rGroupType = new Uint8Array(1) this._rGroupType = new Uint8Array(1)
this._rGroupType[0] = rGroupType; this._rGroupType[0] = rGroupType
} }
set rGroupApprovalThreshold(rGroupApprovalThreshold) { set rGroupApprovalThreshold(rGroupApprovalThreshold) {
this._rGroupApprovalThreshold = new Uint8Array(1) this._rGroupApprovalThreshold = new Uint8Array(1)
this._rGroupApprovalThreshold[0] = rGroupApprovalThreshold; this._rGroupApprovalThreshold[0] = rGroupApprovalThreshold
} }
set rGroupMinimumBlockDelay(rGroupMinimumBlockDelay) { set rGroupMinimumBlockDelay(rGroupMinimumBlockDelay) {
this._rGroupMinimumBlockDelay = rGroupMinimumBlockDelay; this._rGroupMinimumBlockDelay = rGroupMinimumBlockDelay
this._rGroupMinimumBlockDelayBytes = this.constructor.utils.int32ToBytes(this._rGroupMinimumBlockDelay) this._rGroupMinimumBlockDelayBytes = this.constructor.utils.int32ToBytes(this._rGroupMinimumBlockDelay)
} }
set rGroupMaximumBlockDelay(rGroupMaximumBlockDelay) { set rGroupMaximumBlockDelay(rGroupMaximumBlockDelay) {
this._rGroupMaximumBlockDelay = rGroupMaximumBlockDelay; this._rGroupMaximumBlockDelay = rGroupMaximumBlockDelay
this._rGroupMaximumBlockDelayBytes = this.constructor.utils.int32ToBytes(this._rGroupMaximumBlockDelay) this._rGroupMaximumBlockDelayBytes = this.constructor.utils.int32ToBytes(this._rGroupMaximumBlockDelay)
} }
get params() { get params() {
const params = super.params; const params = super.params
params.push( params.push(
this._rGroupNameLength, this._rGroupNameLength,
this._rGroupNameBytes, this._rGroupNameBytes,
this._rGroupDescLength, this._rGroupDescLength,
this._rGroupDescBytes, this._rGroupDescBytes,
this._rGroupType, this._rGroupType,
this._rGroupApprovalThreshold, this._rGroupApprovalThreshold,
this._rGroupMinimumBlockDelayBytes, this._rGroupMinimumBlockDelayBytes,
this._rGroupMaximumBlockDelayBytes, this._rGroupMaximumBlockDelayBytes,
this._feeBytes this._feeBytes
) )
return params; return params
} }
} }

View File

@ -1,67 +1,67 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class GroupBanTransaction extends TransactionBase { export default class GroupBanTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 26 this.type = 26
} }
render(html) { render(html) {
return html` return html`
${this._banMemberDialog1} ${this._banMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._banMemberDialog2} ${this._banMemberDialog2}
` `
} }
set banMemberDialog1(banMemberDialog1) { set banMemberDialog1(banMemberDialog1) {
this._banMemberDialog1= banMemberDialog1 this._banMemberDialog1 = banMemberDialog1
} }
set banMemberDialog2(banMemberDialog2) { set banMemberDialog2(banMemberDialog2) {
this._banMemberDialog2 = banMemberDialog2 this._banMemberDialog2 = banMemberDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set rBanReason(rBanReason) { set rBanReason(rBanReason) {
this._rBanReason = rBanReason this._rBanReason = rBanReason
this._rBanReasonBytes = this.constructor.utils.stringtoUTF8Array(this._rBanReason.toLocaleLowerCase()) this._rBanReasonBytes = this.constructor.utils.stringtoUTF8Array(this._rBanReason.toLocaleLowerCase())
this._rBanReasonLength = this.constructor.utils.int32ToBytes(this._rBanReasonBytes.length) this._rBanReasonLength = this.constructor.utils.int32ToBytes(this._rBanReasonBytes.length)
} }
set rBanTime(rBanTime) { set rBanTime(rBanTime) {
this._rBanTime = rBanTime this._rBanTime = rBanTime
this._rBanTimeBytes = this.constructor.utils.int32ToBytes(this._rBanTime) this._rBanTimeBytes = this.constructor.utils.int32ToBytes(this._rBanTime)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._rBanReasonLength, this._rBanReasonLength,
this._rBanReasonBytes, this._rBanReasonBytes,
this._rBanTimeBytes, this._rBanTimeBytes,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,59 +1,59 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class GroupInviteTransaction extends TransactionBase { export default class GroupInviteTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 29 this.type = 29
} }
render(html) { render(html) {
return html` return html`
${this._inviteMemberDialog1} ${this._inviteMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._inviteMemberDialog2} ${this._inviteMemberDialog2}
` `
} }
set inviteMemberDialog1(inviteMemberDialog1) { set inviteMemberDialog1(inviteMemberDialog1) {
this._inviteMemberDialog1= inviteMemberDialog1 this._inviteMemberDialog1 = inviteMemberDialog1
} }
set inviteMemberDialog2(inviteMemberDialog2) { set inviteMemberDialog2(inviteMemberDialog2) {
this._inviteMemberDialog2 = inviteMemberDialog2 this._inviteMemberDialog2 = inviteMemberDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set rInviteTime(rInviteTime) { set rInviteTime(rInviteTime) {
this._rInviteTime = rInviteTime this._rInviteTime = rInviteTime
this._rInviteTimeBytes = this.constructor.utils.int32ToBytes(this._rInviteTime) this._rInviteTimeBytes = this.constructor.utils.int32ToBytes(this._rInviteTime)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._rInviteTimeBytes, this._rInviteTimeBytes,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,61 +1,61 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class GroupKickTransaction extends TransactionBase { export default class GroupKickTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 28 this.type = 28
} }
render(html) { render(html) {
return html` return html`
${this._kickMemberDialog1} ${this._kickMemberDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._kickMemberDialog2} ${this._kickMemberDialog2}
` `
} }
set kickMemberDialog1(kickMemberDialog1) { set kickMemberDialog1(kickMemberDialog1) {
this._kickMemberDialog1= kickMemberDialog1 this._kickMemberDialog1 = kickMemberDialog1
} }
set kickMemberDialog2(kickMemberDialog2) { set kickMemberDialog2(kickMemberDialog2) {
this._kickMemberDialog2 = kickMemberDialog2 this._kickMemberDialog2 = kickMemberDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set rBanReason(rBanReason) { set rBanReason(rBanReason) {
this._rBanReason = rBanReason this._rBanReason = rBanReason
this._rBanReasonBytes = this.constructor.utils.stringtoUTF8Array(this._rBanReason.toLocaleLowerCase()) this._rBanReasonBytes = this.constructor.utils.stringtoUTF8Array(this._rBanReason.toLocaleLowerCase())
this._rBanReasonLength = this.constructor.utils.int32ToBytes(this._rBanReasonBytes.length) this._rBanReasonLength = this.constructor.utils.int32ToBytes(this._rBanReasonBytes.length)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._rBanReasonLength, this._rBanReasonLength,
this._rBanReasonBytes, this._rBanReasonBytes,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,63 +1,55 @@
"use strict"; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class JoinGroupTransaction extends TransactionBase { export default class JoinGroupTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 31 this.type = 31
this.tests.push( }
() => {
if (!(this._registrantAddress instanceof Uint8Array && this._registrantAddress.length == 25)) {
return "Invalid Registrant " + Base58.encode(this._registrantAddress)
}
return true
}
)
}
render(html) { render(html) {
return html` return html`
${this._groupdialog1} ${this._groupdialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rGroupName}</span> <span style="color: #000;">${this._rGroupName}</span>
</div> </div>
${this._groupdialog2} ${this._groupdialog2}
` `
} }
set groupdialog1(groupdialog1) { set groupdialog1(groupdialog1) {
this._groupdialog1 = groupdialog1 this._groupdialog1 = groupdialog1
} }
set groupdialog2(groupdialog2) { set groupdialog2(groupdialog2) {
this._groupdialog2 = groupdialog2 this._groupdialog2 = groupdialog2
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set registrantAddress(registrantAddress) {// Always Base58 encoded. Accepts Uint8Array or Base58 string. set registrantAddress(registrantAddress) {
this._registrantAddress = registrantAddress instanceof Uint8Array ? registrantAddress : this.constructor.Base58.decode(registrantAddress); this._registrantAddress = registrantAddress instanceof Uint8Array ? registrantAddress : this.constructor.Base58.decode(registrantAddress)
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set rGroupName(rGroupName) { set rGroupName(rGroupName) {
this._rGroupName = rGroupName; this._rGroupName = rGroupName
} }
get params() { get params() {
const params = super.params; const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._feeBytes this._feeBytes
) )
return params; return params
} }
} }

View File

@ -1,64 +1,55 @@
"use strict"; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class LeaveGroupTransaction extends TransactionBase { export default class LeaveGroupTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 32 this.type = 32
this.tests.push( }
() => {
if (!(this._registrantAddress instanceof Uint8Array && this._registrantAddress.length == 25)) {
return "Invalid Registrant " + Base58.encode(this._registrantAddress)
}
return true
}
)
}
render(html) { render(html) {
return html` return html`
${this._groupdialog3} ${this._groupdialog3}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._rGroupName}</span> <span style="color: #000;">${this._rGroupName}</span>
</div> </div>
${this._groupdialog4} ${this._groupdialog4}
` `
} }
set groupdialog3(groupdialog3) { set groupdialog3(groupdialog3) {
this._groupdialog3 = groupdialog3 this._groupdialog3 = groupdialog3
} }
set groupdialog4(groupdialog4) { set groupdialog4(groupdialog4) {
this._groupdialog4 = groupdialog4 this._groupdialog4 = groupdialog4
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set registrantAddress(registrantAddress) {// Always Base58 encoded. Accepts Uint8Array or Base58 string. set registrantAddress(registrantAddress) {
this._registrantAddress = registrantAddress instanceof Uint8Array ? registrantAddress : this.constructor.Base58.decode(registrantAddress); this._registrantAddress = registrantAddress instanceof Uint8Array ? registrantAddress : this.constructor.Base58.decode(registrantAddress)
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set rGroupName(rGroupName) { set rGroupName(rGroupName) {
this._rGroupName = rGroupName; this._rGroupName = rGroupName
} }
get params() { get params() {
const params = super.params; const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._feeBytes this._feeBytes
) )
console.log('check exec params2', params) return params
return params; }
}
} }

View File

@ -1,53 +1,53 @@
'use strict'; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class RemoveGroupAdminTransaction extends TransactionBase { export default class RemoveGroupAdminTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 25 this.type = 25
} }
render(html) { render(html) {
return html` return html`
${this._kickAdminDialog1} ${this._kickAdminDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.theRecipient}</span> <span style="color: #000;">${this.theRecipient}</span>
</div> </div>
${this._kickAdminDialog2} ${this._kickAdminDialog2}
` `
} }
set kickAdminDialog1(kickAdminDialog1) { set kickAdminDialog1(kickAdminDialog1) {
this._kickAdminDialog1 = kickAdminDialog1 this._kickAdminDialog1 = kickAdminDialog1
} }
set kickAdminDialog2(kickAdminDialog2) { set kickAdminDialog2(kickAdminDialog2) {
this._kickAdminDialog2 = kickAdminDialog2 this._kickAdminDialog2 = kickAdminDialog2
} }
set rGroupId(rGroupId) { set rGroupId(rGroupId) {
this._rGroupId = rGroupId; this._rGroupId = rGroupId
this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId) this._rGroupIdBytes = this.constructor.utils.int32ToBytes(this._rGroupId)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._rGroupIdBytes, this._rGroupIdBytes,
this._recipient, this._recipient,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,70 +1,70 @@
'use strict'; 'use strict'
import TransactionBase from '../TransactionBase.js' import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js' import { QORT_DECIMALS } from '../../constants.js'
export default class BuyNameTransacion extends TransactionBase { export default class BuyNameTransacion extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 7 this.type = 7
} }
render(html) { render(html) {
return html` return html`
${this._buyNameDialog1} ${this._buyNameDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span> <span style="color: #000;">${this.nameText}</span>
</div> </div>
${this._buyNameDialog2} ${this._buyNameDialog2}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.showSellPrice}</span> <span style="color: #000;">${this.showSellPrice}</span>
</div> </div>
${this._buyNameDialog3} ${this._buyNameDialog3}
` `
} }
set buyNameDialog1(buyNameDialog1) { set buyNameDialog1(buyNameDialog1) {
this._buyNameDialog1 = buyNameDialog1 this._buyNameDialog1 = buyNameDialog1
} }
set buyNameDialog2(buyNameDialog2) { set buyNameDialog2(buyNameDialog2) {
this._buyNameDialog2 = buyNameDialog2 this._buyNameDialog2 = buyNameDialog2
} }
set buyNameDialog3(buyNameDialog3) { set buyNameDialog3(buyNameDialog3) {
this._buyNameDialog3 = buyNameDialog3 this._buyNameDialog3 = buyNameDialog3
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set name(name) { set name(name) {
this.nameText = name this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name) this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length) this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
} }
set sellPrice(sellPrice) { set sellPrice(sellPrice) {
this.showSellPrice = sellPrice this.showSellPrice = sellPrice
this._sellPrice = sellPrice * QORT_DECIMALS this._sellPrice = sellPrice * QORT_DECIMALS
this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice) this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice)
} }
set recipient(recipient) { set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.theRecipient = recipient this.theRecipient = recipient
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._nameLength, this._nameLength,
this._nameBytes, this._nameBytes,
this._sellPriceBytes, this._sellPriceBytes,
this._recipient, this._recipient,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,49 +1,49 @@
'use strict'; 'use strict'
import TransactionBase from '../TransactionBase.js' import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js' import { QORT_DECIMALS } from '../../constants.js'
export default class CancelSellNameTransacion extends TransactionBase { export default class CancelSellNameTransacion extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 6 this.type = 6
} }
render(html) { render(html) {
return html` return html`
${this._cancelSellNameDialog1} ${this._cancelSellNameDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span> <span style="color: #000;">${this.nameText}</span>
</div> </div>
${this._cancelSellNameDialog2} ${this._cancelSellNameDialog2}
` `
} }
set cancelSellNameDialog1(cancelSellNameDialog1) { set cancelSellNameDialog1(cancelSellNameDialog1) {
this._cancelSellNameDialog1 = cancelSellNameDialog1 this._cancelSellNameDialog1 = cancelSellNameDialog1
} }
set cancelSellNameDialog2(cancelSellNameDialog2) { set cancelSellNameDialog2(cancelSellNameDialog2) {
this._cancelSellNameDialog2 = cancelSellNameDialog2 this._cancelSellNameDialog2 = cancelSellNameDialog2
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set name(name) { set name(name) {
this.nameText = name this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name) this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length) this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._nameLength, this._nameLength,
this._nameBytes, this._nameBytes,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,57 +1,57 @@
"use strict"; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from "../../constants.js" import { QORT_DECIMALS } from '../../constants.js'
export default class RegisterNameTransaction extends TransactionBase { export default class RegisterNameTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 3 this.type = 3
} }
render(html) { render(html) {
return html` return html`
${this._dialogyou} ${this._dialogyou}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span> <span style="color: #000;">${this.nameText}</span>
</div> </div>
${this._dialogonpress} ${this._dialogonpress}
` `
} }
set dialogyou(dialogyou) { set dialogyou(dialogyou) {
this._dialogyou = dialogyou this._dialogyou = dialogyou
} }
set dialogonpress(dialogonpress) { set dialogonpress(dialogonpress) {
this._dialogonpress = dialogonpress this._dialogonpress = dialogonpress
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set name(name) { set name(name) {
this.nameText = name; this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name) this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length) this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
} }
set value(value) { set value(value) {
this.valueText = value.length === 0 ? "Registered Name on the Qortal Chain" : value; this.valueText = value.length === 0 ? "Registered Name on the Qortal Chain" : value
this._valueBytes = this.constructor.utils.stringtoUTF8Array(this.valueText) this._valueBytes = this.constructor.utils.stringtoUTF8Array(this.valueText)
this._valueLength = this.constructor.utils.int32ToBytes(this._valueBytes.length) this._valueLength = this.constructor.utils.int32ToBytes(this._valueBytes.length)
} }
get params() { get params() {
const params = super.params; const params = super.params
params.push( params.push(
this._nameLength, this._nameLength,
this._nameBytes, this._nameBytes,
this._valueLength, this._valueLength,
this._valueBytes, this._valueBytes,
this._feeBytes this._feeBytes
) )
return params; return params
} }
} }

View File

@ -1,64 +1,64 @@
'use strict'; 'use strict'
import TransactionBase from '../TransactionBase.js' import TransactionBase from '../TransactionBase.js'
import { QORT_DECIMALS } from '../../constants.js' import { QORT_DECIMALS } from '../../constants.js'
export default class SellNameTransacion extends TransactionBase { export default class SellNameTransacion extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 5 this.type = 5
} }
render(html) { render(html) {
return html` return html`
${this._sellNameDialog1} ${this._sellNameDialog1}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.nameText}</span> <span style="color: #000;">${this.nameText}</span>
</div> </div>
${this._sellNameDialog2} ${this._sellNameDialog2}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.showSellPrice}</span> <span style="color: #000;">${this.showSellPrice}</span>
</div> </div>
${this._sellNameDialog3} ${this._sellNameDialog3}
` `
} }
set sellNameDialog1(sellNameDialog1) { set sellNameDialog1(sellNameDialog1) {
this._sellNameDialog1 = sellNameDialog1 this._sellNameDialog1 = sellNameDialog1
} }
set sellNameDialog2(sellNameDialog2) { set sellNameDialog2(sellNameDialog2) {
this._sellNameDialog2 = sellNameDialog2 this._sellNameDialog2 = sellNameDialog2
} }
set sellNameDialog3(sellNameDialog3) { set sellNameDialog3(sellNameDialog3) {
this._sellNameDialog3 = sellNameDialog3 this._sellNameDialog3 = sellNameDialog3
} }
set fee(fee) { set fee(fee) {
this._fee = fee * QORT_DECIMALS this._fee = fee * QORT_DECIMALS
this._feeBytes = this.constructor.utils.int64ToBytes(this._fee) this._feeBytes = this.constructor.utils.int64ToBytes(this._fee)
} }
set name(name) { set name(name) {
this.nameText = name this.nameText = name
this._nameBytes = this.constructor.utils.stringtoUTF8Array(name) this._nameBytes = this.constructor.utils.stringtoUTF8Array(name)
this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length) this._nameLength = this.constructor.utils.int32ToBytes(this._nameBytes.length)
} }
set sellPrice(sellPrice) { set sellPrice(sellPrice) {
this.showSellPrice = sellPrice this.showSellPrice = sellPrice
this._sellPrice = sellPrice * QORT_DECIMALS this._sellPrice = sellPrice * QORT_DECIMALS
this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice) this._sellPriceBytes = this.constructor.utils.int64ToBytes(this._sellPrice)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._nameLength, this._nameLength,
this._nameBytes, this._nameBytes,
this._sellPriceBytes, this._sellPriceBytes,
this._feeBytes this._feeBytes
) )
return params return params
} }
} }

View File

@ -1,39 +1,36 @@
"use strict"; 'use strict'
/*
TO DO
*/
(function(){
function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) => {
const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp);
return nacl.sign.detached(data, keyPair.privateKey);
}
function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) => { (function () {
return appendBuffer( generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), function generateSignatureRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp) => {
signature ); const data = generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp)
} return nacl.sign.detached(data, keyPair.privateKey)
}
function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) => { function generateRegisterNameTransaction(keyPair, lastReference, owner, name, value, fee, timestamp, signature) => {
const txType = TYPES.REGISTER_NAME_TRANSACTION; return appendBuffer(generateRegisterNameTransactionBase(keyPair.publicKey, lastReference, owner, name, value, fee, timestamp), signature)
const typeBytes = int32ToBytes(txType); }
const timestampBytes = int64ToBytes(timestamp);
const feeBytes = int64ToBytes(fee * 100000000);
const nameSizeBytes = int32ToBytes(name.length);
const valueSizeBytes = int32ToBytes(value.length);
let data = new Uint8Array(); function generateRegisterNameTransactionBase(publicKey, lastReference, owner, name, value, fee, timestamp) => {
const txType = TYPES.REGISTER_NAME_TRANSACTION
const typeBytes = int32ToBytes(txType)
const timestampBytes = int64ToBytes(timestamp)
const feeBytes = int64ToBytes(fee * 100000000)
const nameSizeBytes = int32ToBytes(name.length)
const valueSizeBytes = int32ToBytes(value.length)
data = appendBuffer(data, typeBytes); let data = new Uint8Array()
data = appendBuffer(data, timestampBytes);
data = appendBuffer(data, lastReference);
data = appendBuffer(data, publicKey);
data = appendBuffer(data, owner);
data = appendBuffer(data, nameSizeBytes);
data = appendBuffer(data, name);
data = appendBuffer(data, valueSizeBytes);
data = appendBuffer(data, value);
data = appendBuffer(data, feeBytes);
return data; data = appendBuffer(data, typeBytes)
} data = appendBuffer(data, timestampBytes)
}()) data = appendBuffer(data, lastReference)
data = appendBuffer(data, publicKey)
data = appendBuffer(data, owner)
data = appendBuffer(data, nameSizeBytes)
data = appendBuffer(data, name)
data = appendBuffer(data, valueSizeBytes)
data = appendBuffer(data, value)
data = appendBuffer(data, feeBytes)
return data
}
}())

View File

@ -1,55 +1,55 @@
"use strict"; 'use strict'
import TransactionBase from "../TransactionBase.js" import TransactionBase from '../TransactionBase.js'
import publicKeyToAddress from '../../wallet/publicKeyToAddress.js' import publicKeyToAddress from '../../wallet/publicKeyToAddress.js'
import { Base58 } from "../../deps/deps.js"; import { Base58 } from '../../deps/deps.js'
export default class RemoveRewardShareTransaction extends TransactionBase { export default class RemoveRewardShareTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 38 this.type = 38
} }
render(html) { render(html) {
return html` return html`
${this._rewarddialog5} ${this._rewarddialog5}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this.constructor.Base58.encode(this._recipient)}</span> <span style="color: #000;">${this.constructor.Base58.encode(this._recipient)}</span>
</div> </div>
${this._rewarddialog6} ${this._rewarddialog6}
` `
} }
set rewarddialog5(rewarddialog5) { set rewarddialog5(rewarddialog5) {
this._rewarddialog5 = rewarddialog5; this._rewarddialog5 = rewarddialog5
} }
set rewarddialog6(rewarddialog6) { set rewarddialog6(rewarddialog6) {
this._rewarddialog6 = rewarddialog6; this._rewarddialog6 = rewarddialog6
} }
set rewardShareKeyPairPublicKey(rewardShareKeyPairPublicKey) { set rewardShareKeyPairPublicKey(rewardShareKeyPairPublicKey) {
this._rewardShareKeyPairPublicKey = Base58.decode(rewardShareKeyPairPublicKey) this._rewardShareKeyPairPublicKey = Base58.decode(rewardShareKeyPairPublicKey)
} }
set recipient(recipient) { set recipient(recipient) {
const _address = publicKeyToAddress(this._keyPair.publicKey) const _address = publicKeyToAddress(this._keyPair.publicKey)
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
this.fee = _address === recipient ? 0 : 0.001 this.fee = _address === recipient ? 0 : 0.001
} }
set percentageShare(share) { set percentageShare(share) {
this._percentageShare = share * 100 this._percentageShare = share * 100
this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare) this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._recipient, this._recipient,
this._rewardShareKeyPairPublicKey, this._rewardShareKeyPairPublicKey,
this._percentageShareBytes, this._percentageShareBytes,
this._feeBytes this._feeBytes
) )
return params; return params
} }
} }

View File

@ -1,4 +1,4 @@
"use strict"; 'use strict'
import publicKeyToAddress from '../../wallet/publicKeyToAddress.js' import publicKeyToAddress from '../../wallet/publicKeyToAddress.js'
import TransactionBase from "../TransactionBase.js" import TransactionBase from "../TransactionBase.js"
import nacl from '../../deps/nacl-fast.js' import nacl from '../../deps/nacl-fast.js'
@ -6,74 +6,73 @@ import ed2curve from '../../deps/ed2curve.js'
import { Sha256 } from 'asmcrypto.js' import { Sha256 } from 'asmcrypto.js'
export default class RewardShareTransaction extends TransactionBase { export default class RewardShareTransaction extends TransactionBase {
constructor() { constructor() {
super() super()
this.type = 38 this.type = 38
} }
render(html) { render(html) {
return html` return html`
${this._rewarddialog1} <strong>${this._percentageShare / 1e8}%</strong> ${this._rewarddialog2} <strong>${this.constructor.Base58.encode(this._recipient)}</strong>? ${this._rewarddialog1} <strong>${this._percentageShare / 1e8}%</strong> ${this._rewarddialog2} <strong>${this.constructor.Base58.encode(this._recipient)}</strong>?
${this._rewarddialog3} ${this._rewarddialog3}
<div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;"> <div style="background: #eee; padding: 8px; margin: 8px 0; border-radius: 5px;">
<span style="color: #000;">${this._base58RewardShareSeed}</span> <span style="color: #000;">${this._base58RewardShareSeed}</span>
</div> </div>
${this._rewarddialog4} ${this._rewarddialog4}
` `
} }
set rewarddialog1(rewarddialog1) { set rewarddialog1(rewarddialog1) {
this._rewarddialog1 = rewarddialog1; this._rewarddialog1 = rewarddialog1
} }
set rewarddialog2(rewarddialog2) { set rewarddialog2(rewarddialog2) {
this._rewarddialog2 = rewarddialog2; this._rewarddialog2 = rewarddialog2
} }
set rewarddialog3(rewarddialog3) { set rewarddialog3(rewarddialog3) {
this._rewarddialog3 = rewarddialog3; this._rewarddialog3 = rewarddialog3
} }
set rewarddialog4(rewarddialog4) { set rewarddialog4(rewarddialog4) {
this._rewarddialog4 = rewarddialog4; this._rewarddialog4 = rewarddialog4
} }
set recipientPublicKey(recipientPublicKey) { set recipientPublicKey(recipientPublicKey) {
this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey this._base58RecipientPublicKey = recipientPublicKey instanceof Uint8Array ? this.constructor.Base58.encode(recipientPublicKey) : recipientPublicKey
this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey) this._recipientPublicKey = this.constructor.Base58.decode(this._base58RecipientPublicKey)
this.recipient = publicKeyToAddress(this._recipientPublicKey) this.recipient = publicKeyToAddress(this._recipientPublicKey)
this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.001) this.fee = (recipientPublicKey === this.constructor.Base58.encode(this._keyPair.publicKey) ? 0 : 0.001)
// Reward share keys const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey)
const convertedPrivateKey = ed2curve.convertSecretKey(this._keyPair.privateKey) const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey)
const convertedPublicKey = ed2curve.convertPublicKey(this._recipientPublicKey) const sharedSecret = new Uint8Array(32);
const sharedSecret = new Uint8Array(32); nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey);
nacl.lowlevel.crypto_scalarmult(sharedSecret, convertedPrivateKey, convertedPublicKey); this._rewardShareSeed = new Sha256().process(sharedSecret).finish().result
this._rewardShareSeed = new Sha256().process(sharedSecret).finish().result this._base58RewardShareSeed = this.constructor.Base58.encode(this._rewardShareSeed)
this._base58RewardShareSeed = this.constructor.Base58.encode(this._rewardShareSeed)
this._rewardShareKeyPair = nacl.sign.keyPair.fromSeed(this._rewardShareSeed) this._rewardShareKeyPair = nacl.sign.keyPair.fromSeed(this._rewardShareSeed)
} }
set recipient(recipient) { // Always Base58 encoded. Accepts Uint8Array or Base58 string. set recipient(recipient) {
this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient) this._recipient = recipient instanceof Uint8Array ? recipient : this.constructor.Base58.decode(recipient)
} }
set percentageShare(share) { set percentageShare(share) {
this._percentageShare = share * 100 this._percentageShare = share * 100
this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare) this._percentageShareBytes = this.constructor.utils.int64ToBytes(this._percentageShare)
} }
get params() { get params() {
const params = super.params const params = super.params
params.push( params.push(
this._recipient, this._recipient,
this._rewardShareKeyPair.publicKey, this._rewardShareKeyPair.publicKey,
this._percentageShareBytes, this._percentageShareBytes,
this._feeBytes this._feeBytes
) )
return params; return params
} }
} }

View File

@ -5,75 +5,59 @@
*/ */
export default class TradeBotCreateRequest { export default class TradeBotCreateRequest {
constructor() { constructor() {
// ... // ...
} }
createTransaction(txnReq) { createTransaction(txnReq) {
this.creatorPublicKey(txnReq.creatorPublicKey)
this.qortAmount(txnReq.qortAmount)
this.fundingQortAmount(txnReq.fundingQortAmount)
this.foreignBlockchain(txnReq.foreignBlockchain)
this.foreignAmount(txnReq.foreignAmount)
this.tradeTimeout(txnReq.tradeTimeout)
this.receivingAddress(txnReq.receivingAddress)
this.creatorPublicKey(txnReq.creatorPublicKey); return this.txnRequest()
}
this.qortAmount(txnReq.qortAmount); creatorPublicKey(creatorPublicKey) {
this._creatorPublicKey = creatorPublicKey
}
this.fundingQortAmount(txnReq.fundingQortAmount); qortAmount(qortAmount) {
this._qortAmount = qortAmount
}
this.foreignBlockchain(txnReq.foreignBlockchain); fundingQortAmount(fundingQortAmount) {
this._fundingQortAmount = fundingQortAmount
}
this.foreignAmount(txnReq.foreignAmount); foreignBlockchain(foreignBlockchain) {
this._foreignBlockchain = foreignBlockchain
}
this.tradeTimeout(txnReq.tradeTimeout); foreignAmount(foreignAmount) {
this._foreignAmount = foreignAmount
}
this.receivingAddress(txnReq.receivingAddress); tradeTimeout(tradeTimeout) {
this._tradeTimeout = tradeTimeout
}
return this.txnRequest(); receivingAddress(receivingAddress) {
} this._receivingAddress = receivingAddress
}
creatorPublicKey(creatorPublicKey) { txnRequest() {
return {
this._creatorPublicKey = creatorPublicKey; creatorPublicKey: this._creatorPublicKey,
qortAmount: this._qortAmount,
} fundingQortAmount: this._fundingQortAmount,
foreignBlockchain: this._foreignBlockchain,
qortAmount(qortAmount) { foreignAmount: this._foreignAmount,
this._qortAmount = qortAmount; tradeTimeout: this._tradeTimeout,
} receivingAddress: this._receivingAddress
}
}
fundingQortAmount(fundingQortAmount) {
this._fundingQortAmount = fundingQortAmount;
}
foreignBlockchain(foreignBlockchain) {
this._foreignBlockchain = foreignBlockchain;
}
foreignAmount(foreignAmount) {
this._foreignAmount = foreignAmount;
}
tradeTimeout(tradeTimeout) {
this._tradeTimeout = tradeTimeout;
}
receivingAddress(receivingAddress) {
this._receivingAddress = receivingAddress;
}
txnRequest() {
return {
creatorPublicKey: this._creatorPublicKey,
qortAmount: this._qortAmount,
fundingQortAmount: this._fundingQortAmount,
foreignBlockchain: this._foreignBlockchain,
foreignAmount: this._foreignAmount,
tradeTimeout: this._tradeTimeout,
receivingAddress: this._receivingAddress
}
}
} }

View File

@ -5,41 +5,35 @@
*/ */
export default class TradeBotRespondRequest { export default class TradeBotRespondRequest {
constructor() { constructor() {
// ... // ...
} }
createTransaction(txnReq) { createTransaction(txnReq) {
this.atAddress(txnReq.atAddress)
this.foreignKey(txnReq.foreignKey)
this.receivingAddress(txnReq.receivingAddress)
this.atAddress(txnReq.atAddress) return this.txnRequest()
}
this.foreignKey(txnReq.foreignKey) atAddress(atAddress) {
this._atAddress = atAddress
}
this.receivingAddress(txnReq.receivingAddress) foreignKey(foreignKey) {
this._foreignKey = foreignKey
}
return this.txnRequest() receivingAddress(receivingAddress) {
} this._receivingAddress = receivingAddress
}
atAddress(atAddress) { txnRequest() {
return {
this._atAddress = atAddress atAddress: this._atAddress,
} foreignKey: this._foreignKey,
receivingAddress: this._receivingAddress
foreignKey(foreignKey) { }
this._foreignKey = foreignKey }
}
receivingAddress(receivingAddress) {
this._receivingAddress = receivingAddress
}
txnRequest() {
return {
atAddress: this._atAddress,
foreignKey: this._foreignKey,
receivingAddress: this._receivingAddress
}
}
} }

View File

@ -2,37 +2,30 @@ import Base58 from '../../../deps/Base58.js'
import nacl from '../../../deps/nacl-fast.js' import nacl from '../../../deps/nacl-fast.js'
import utils from '../../../deps/utils.js' import utils from '../../../deps/utils.js'
const signTradeBotTransaction = (unsignedTxn, keyPair) => { const signTradeBotTransaction = (unsignedTxn, keyPair) => {
if (!unsignedTxn) {
throw new Error('Unsigned Transaction Bytes not defined')
}
if (!unsignedTxn) { if (!keyPair) {
throw new Error('Unsigned Transaction Bytes not defined') throw new Error('keyPair not defined')
} }
if (!keyPair) { const txnBuffer = Base58.decode(unsignedTxn)
throw new Error('keyPair not defined')
}
const txnBuffer = Base58.decode(unsignedTxn) if (keyPair.privateKey.length === undefined) {
const _privateKey = Object.keys(keyPair.privateKey).map(function (key) { return keyPair.privateKey[key]; })
const privateKey = new Uint8Array(_privateKey)
const signature = nacl.sign.detached(txnBuffer, privateKey)
const signedBytes = utils.appendBuffer(txnBuffer, signature)
if (keyPair.privateKey.length === undefined) { return signedBytes
} else {
const signature = nacl.sign.detached(txnBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(txnBuffer, signature)
const _privateKey = Object.keys(keyPair.privateKey).map(function (key) { return keyPair.privateKey[key]; }); return signedBytes
const privateKey = new Uint8Array(_privateKey) }
const signature = nacl.sign.detached(txnBuffer, privateKey)
const signedBytes = utils.appendBuffer(txnBuffer, signature)
return signedBytes
} else {
const signature = nacl.sign.detached(txnBuffer, keyPair.privateKey)
const signedBytes = utils.appendBuffer(txnBuffer, signature)
return signedBytes
}
} }
export default signTradeBotTransaction export default signTradeBotTransaction

Some files were not shown because too many files have changed in this diff Show More