Upgrade Electrum base to 3.3.8

This commit is contained in:
Madiator2011 2020-02-17 23:42:13 +01:00
parent a6e3a244e8
commit 43a67ef148
119 changed files with 4882 additions and 735 deletions

View file

@ -0,0 +1,36 @@
Building Mac OS binaries
========================
This guide explains how to build Electrum binaries for macOS systems.
The build process consists of two steps:
## 1. Building the binary
This needs to be done on a system running macOS or OS X. We use El Capitan (10.11.6) as building it on High Sierra
makes the binaries incompatible with older versions.
Before starting, make sure that the Xcode command line tools are installed (e.g. you have `git`).
cd electrum
./contrib/build-osx/make_osx
This creates a folder named Electrum.app.
## 2. Building the image
The usual way to distribute macOS applications is to use image files containing the
application. Although these images can be created on a Mac with the built-in `hdiutil`,
they are not deterministic.
Instead, we use the toolchain that Bitcoin uses: genisoimage and libdmg-hfsplus.
These tools do not work on macOS, so you need a separate Linux machine (or VM).
Copy the Electrum.app directory over and install the dependencies, e.g.:
apt install libcap-dev cmake make gcc faketime
Then you can just invoke `package.sh` with the path to the app:
cd electrum
./contrib/build-osx/package.sh ~/Electrum.app/

12
contrib/build-osx/base.sh Normal file
View file

@ -0,0 +1,12 @@
#!/usr/bin/env bash
RED='\033[0;31m'
BLUE='\033[0,34m'
NC='\033[0m' # No Color
function info {
printf "\r💬 ${BLUE}INFO:${NC} ${1}\n"
}
function fail {
printf "\r🗯 ${RED}ERROR:${NC} ${1}\n"
exit 1
}

View file

@ -0,0 +1,86 @@
--- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400
+++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500
@@ -1139,8 +1139,9 @@
scan_directory_tree(struct directory *this_dir, char *path,
struct directory_entry *de)
{
- DIR *current_dir;
+ int current_file;
char whole_path[PATH_MAX];
+ struct dirent **d_list;
struct dirent *d_entry;
struct directory *parent;
int dflag;
@@ -1164,7 +1165,8 @@
this_dir->dir_flags |= DIR_WAS_SCANNED;
errno = 0; /* Paranoia */
- current_dir = opendir(path);
+ //current_dir = opendir(path);
+ current_file = scandir(path, &d_list, NULL, alphasort);
d_entry = NULL;
/*
@@ -1173,12 +1175,12 @@
*/
old_path = path;
- if (current_dir) {
+ if (current_file >= 0) {
errno = 0;
- d_entry = readdir(current_dir);
+ d_entry = d_list[0];
}
- if (!current_dir || !d_entry) {
+ if (current_file < 0 || !d_entry) {
int ret = 1;
#ifdef USE_LIBSCHILY
@@ -1191,8 +1193,8 @@
de->isorec.flags[0] &= ~ISO_DIRECTORY;
ret = 0;
}
- if (current_dir)
- closedir(current_dir);
+ if(d_list)
+ free(d_list);
return (ret);
}
#ifdef ABORT_DEEP_ISO_ONLY
@@ -1208,7 +1210,7 @@
errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n");
errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n");
}
- closedir(current_dir);
+ free(d_list);
return (1);
}
#endif
@@ -1250,13 +1252,13 @@
* The first time through, skip this, since we already asked
* for the first entry when we opened the directory.
*/
- if (dflag)
- d_entry = readdir(current_dir);
+ if (dflag && current_file >= 0)
+ d_entry = d_list[current_file];
dflag++;
- if (!d_entry)
+ if (current_file < 0)
break;
-
+ current_file--;
/* OK, got a valid entry */
/* If we do not want all files, then pitch the backups. */
@@ -1348,7 +1350,7 @@
insert_file_entry(this_dir, whole_path, d_entry->d_name);
#endif /* APPLE_HYB */
}
- closedir(current_dir);
+ free(d_list);
#ifdef APPLE_HYB
/*

100
contrib/build-osx/make_osx Normal file
View file

@ -0,0 +1,100 @@
#!/usr/bin/env bash
# Parameterize
PYTHON_VERSION=3.6.4
BUILDDIR=/tmp/electrum-build
PACKAGE=Electrum
GIT_REPO=https://github.com/spesmilo/electrum
LIBSECP_VERSION=452d8e4d2a2f9f1b5be6b02e18f1ba102e5ca0b4
. $(dirname "$0")/base.sh
src_dir=$(dirname "$0")
cd $src_dir/../..
export PYTHONHASHSEED=22
VERSION=`git describe --tags --dirty --always`
which brew > /dev/null 2>&1 || fail "Please install brew from https://brew.sh/ to continue"
info "Installing Python $PYTHON_VERSION"
export PATH="~/.pyenv/bin:~/.pyenv/shims:~/Library/Python/3.6/bin:$PATH"
if [ -d "~/.pyenv" ]; then
pyenv update
else
curl -L https://raw.githubusercontent.com/pyenv/pyenv-installer/master/bin/pyenv-installer | bash > /dev/null 2>&1
fi
PYTHON_CONFIGURE_OPTS="--enable-framework" pyenv install -s $PYTHON_VERSION && \
pyenv global $PYTHON_VERSION || \
fail "Unable to use Python $PYTHON_VERSION"
info "Installing pyinstaller"
python3 -m pip install -I --user pyinstaller==3.4 || fail "Could not install pyinstaller"
info "Using these versions for building $PACKAGE:"
sw_vers
python3 --version
echo -n "Pyinstaller "
pyinstaller --version
rm -rf ./dist
git submodule init
git submodule update
rm -rf $BUILDDIR > /dev/null 2>&1
mkdir $BUILDDIR
cp -R ./contrib/deterministic-build/electrum-locale/locale/ ./electrum/locale/
cp ./contrib/deterministic-build/electrum-icons/icons_rc.py ./electrum/gui/qt/
info "Downloading libusb..."
curl https://homebrew.bintray.com/bottles/libusb-1.0.22.el_capitan.bottle.tar.gz | \
tar xz --directory $BUILDDIR
cp $BUILDDIR/libusb/1.0.22/lib/libusb-1.0.dylib contrib/build-osx
info "Building libsecp256k1"
brew install autoconf automake libtool
git clone https://github.com/bitcoin-core/secp256k1 $BUILDDIR/secp256k1
pushd $BUILDDIR/secp256k1
git reset --hard $LIBSECP_VERSION
git clean -f -x -q
./autogen.sh
./configure --enable-module-recovery --enable-experimental --enable-module-ecdh --disable-jni
make
popd
cp $BUILDDIR/secp256k1/.libs/libsecp256k1.0.dylib contrib/build-osx
info "Installing requirements..."
python3 -m pip install -Ir ./contrib/deterministic-build/requirements.txt --user && \
python3 -m pip install -Ir ./contrib/deterministic-build/requirements-binaries.txt --user || \
fail "Could not install requirements"
info "Installing hardware wallet requirements..."
python3 -m pip install -Ir ./contrib/deterministic-build/requirements-hw.txt --user || \
fail "Could not install hardware wallet requirements"
info "Building $PACKAGE..."
python3 setup.py install --user > /dev/null || fail "Could not build $PACKAGE"
info "Faking timestamps..."
for d in ~/Library/Python/ ~/.pyenv .; do
pushd $d
find . -exec touch -t '200101220000' {} +
popd
done
info "Building binary"
pyinstaller --noconfirm --ascii --clean --name $VERSION contrib/build-osx/osx.spec || fail "Could not build binary"
info "Adding bitcoin URI types to Info.plist"
plutil -insert 'CFBundleURLTypes' \
-xml '<array><dict> <key>CFBundleURLName</key> <string>bitcoin</string> <key>CFBundleURLSchemes</key> <array><string>bitcoin</string></array> </dict></array>' \
-- dist/$PACKAGE.app/Contents/Info.plist \
|| fail "Could not add keys to Info.plist. Make sure the program 'plutil' exists and is installed."
info "Creating .DMG"
hdiutil create -fs HFS+ -volname $PACKAGE -srcfolder dist/$PACKAGE.app dist/electrum-$VERSION.dmg || fail "Could not create .DMG"

104
contrib/build-osx/osx.spec Normal file
View file

@ -0,0 +1,104 @@
# -*- mode: python -*-
from PyInstaller.utils.hooks import collect_data_files, collect_submodules, collect_dynamic_libs
import sys
import os
PACKAGE='Electrum'
PYPKG='electrum'
MAIN_SCRIPT='run_electrum'
ICONS_FILE='electrum.icns'
for i, x in enumerate(sys.argv):
if x == '--name':
VERSION = sys.argv[i+1]
break
else:
raise Exception('no version')
electrum = os.path.abspath(".") + "/"
block_cipher = None
# see https://github.com/pyinstaller/pyinstaller/issues/2005
hiddenimports = []
hiddenimports += collect_submodules('trezorlib')
hiddenimports += collect_submodules('safetlib')
hiddenimports += collect_submodules('btchip')
hiddenimports += collect_submodules('keepkeylib')
hiddenimports += collect_submodules('websocket')
hiddenimports += collect_submodules('ckcc')
datas = [
(electrum + PYPKG + '/*.json', PYPKG),
(electrum + PYPKG + '/wordlist/english.txt', PYPKG + '/wordlist'),
(electrum + PYPKG + '/locale', PYPKG + '/locale'),
(electrum + PYPKG + '/plugins', PYPKG + '/plugins'),
]
datas += collect_data_files('trezorlib')
datas += collect_data_files('safetlib')
datas += collect_data_files('btchip')
datas += collect_data_files('keepkeylib')
datas += collect_data_files('ckcc')
# Add libusb so Trezor and Safe-T mini will work
binaries = [(electrum + "contrib/build-osx/libusb-1.0.dylib", ".")]
binaries += [(electrum + "contrib/build-osx/libsecp256k1.0.dylib", ".")]
# Workaround for "Retro Look":
binaries += [b for b in collect_dynamic_libs('PyQt5') if 'macstyle' in b[0]]
# We don't put these files in to actually include them in the script but to make the Analysis method scan them for imports
a = Analysis([electrum+ MAIN_SCRIPT,
electrum+'electrum/gui/qt/main_window.py',
electrum+'electrum/gui/text.py',
electrum+'electrum/util.py',
electrum+'electrum/wallet.py',
electrum+'electrum/simple_config.py',
electrum+'electrum/bitcoin.py',
electrum+'electrum/dnssec.py',
electrum+'electrum/commands.py',
electrum+'electrum/plugins/cosigner_pool/qt.py',
electrum+'electrum/plugins/email_requests/qt.py',
electrum+'electrum/plugins/trezor/client.py',
electrum+'electrum/plugins/trezor/qt.py',
electrum+'electrum/plugins/safe_t/client.py',
electrum+'electrum/plugins/safe_t/qt.py',
electrum+'electrum/plugins/keepkey/qt.py',
electrum+'electrum/plugins/ledger/qt.py',
electrum+'electrum/plugins/coldcard/qt.py',
],
binaries=binaries,
datas=datas,
hiddenimports=hiddenimports,
hookspath=[])
# http://stackoverflow.com/questions/19055089/pyinstaller-onefile-warning-pyconfig-h-when-importing-scipy-or-scipy-signal
for d in a.datas:
if 'pyconfig' in d[0]:
a.datas.remove(d)
break
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(pyz,
a.scripts,
a.binaries,
a.datas,
name=PACKAGE,
debug=False,
strip=False,
upx=True,
icon=electrum+ICONS_FILE,
console=False)
app = BUNDLE(exe,
version = VERSION,
name=PACKAGE + '.app',
icon=electrum+ICONS_FILE,
bundle_identifier=None,
info_plist={
'NSHighResolutionCapable': 'True',
'NSSupportsAutomaticGraphicsSwitching': 'True'
}
)

View file

@ -0,0 +1,88 @@
#!/usr/bin/env bash
cdrkit_version=1.1.11
cdrkit_download_path=http://distro.ibiblio.org/fatdog/source/600/c
cdrkit_file_name=cdrkit-${cdrkit_version}.tar.bz2
cdrkit_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564
cdrkit_patches=cdrkit-deterministic.patch
genisoimage=genisoimage-$cdrkit_version
libdmg_url=https://github.com/theuni/libdmg-hfsplus
export LD_PRELOAD=$(locate libfaketime.so.1)
export FAKETIME="2000-01-22 00:00:00"
export PATH=$PATH:~/bin
. $(dirname "$0")/base.sh
if [ -z "$1" ]; then
echo "Usage: $0 Electrum.app"
exit -127
fi
mkdir -p ~/bin
if ! which ${genisoimage} > /dev/null 2>&1; then
mkdir -p /tmp/electrum-macos
cd /tmp/electrum-macos
info "Downloading cdrkit $cdrkit_version"
wget -nc ${cdrkit_download_path}/${cdrkit_file_name}
tar xvf ${cdrkit_file_name}
info "Patching genisoimage"
cd cdrkit-${cdrkit_version}
patch -p1 < ../cdrkit-deterministic.patch
info "Building genisoimage"
cmake . -Wno-dev
make genisoimage
cp genisoimage/genisoimage ~/bin/${genisoimage}
fi
if ! which dmg > /dev/null 2>&1; then
mkdir -p /tmp/electrum-macos
cd /tmp/electrum-macos
info "Downloading libdmg"
LD_PRELOAD= git clone ${libdmg_url}
cd libdmg-hfsplus
info "Building libdmg"
cmake .
make
cp dmg/dmg ~/bin
fi
${genisoimage} -version || fail "Unable to install genisoimage"
dmg -|| fail "Unable to install libdmg"
plist=$1/Contents/Info.plist
test -f "$plist" || fail "Info.plist not found"
VERSION=$(grep -1 ShortVersionString $plist |tail -1|gawk 'match($0, /<string>(.*)<\/string>/, a) {print a[1]}')
echo $VERSION
rm -rf /tmp/electrum-macos/image > /dev/null 2>&1
mkdir /tmp/electrum-macos/image/
cp -r $1 /tmp/electrum-macos/image/
build_dir=$(dirname "$1")
test -n "$build_dir" -a -d "$build_dir" || exit
cd $build_dir
${genisoimage} \
-no-cache-inodes \
-D \
-l \
-probe \
-V "Electrum" \
-no-pad \
-r \
-dir-mode 0755 \
-apple \
-o Electrum_uncompressed.dmg \
/tmp/electrum-macos/image || fail "Unable to create uncompressed dmg"
dmg dmg Electrum_uncompressed.dmg electrum-$VERSION.dmg || fail "Unable to create compressed dmg"
rm Electrum_uncompressed.dmg
echo "Done."
md5sum electrum-$VERSION.dmg

View file

@ -0,0 +1,40 @@
#!/bin/bash
# heavily based on https://github.com/ofek/coincurve/blob/417e726f553460f88d7edfa5dc67bfda397c4e4a/.travis/build_windows_wheels.sh
set -e
build_dll() {
#sudo apt-get install -y mingw-w64
export SOURCE_DATE_EPOCH=1530212462
./autogen.sh
echo "LDFLAGS = -no-undefined" >> Makefile.am
LDFLAGS="-Wl,--no-insert-timestamp" ./configure \
--host=$1 \
--enable-module-recovery \
--enable-experimental \
--enable-module-ecdh \
--disable-jni
make
${1}-strip .libs/libsecp256k1-0.dll
}
cd /tmp/electrum-build
if [ ! -d secp256k1 ]; then
git clone https://github.com/bitcoin-core/secp256k1.git
cd secp256k1;
else
cd secp256k1
git pull
fi
git reset --hard 452d8e4d2a2f9f1b5be6b02e18f1ba102e5ca0b4
git clean -f -x -q
build_dll i686-w64-mingw32 # 64-bit would be: x86_64-w64-mingw32
mv .libs/libsecp256k1-0.dll libsecp256k1.dll
find -exec touch -d '2000-11-11T11:11:11+00:00' {} +
echo "building libsecp256k1 finished"

View file

@ -118,7 +118,7 @@ exe_standalone = EXE(
a.scripts,
a.binaries,
a.datas,
name=os.path.join('build\\pyi.win32\\electrum', cmdline_name + ".exe"),
name=os.path.join('build\\pyi.win32\\electrum-lbry', cmdline_name + ".exe"),
debug=False,
strip=None,
upx=False,
@ -131,7 +131,7 @@ exe_portable = EXE(
a.scripts,
a.binaries,
a.datas + [ ('is_portable', 'README.md', 'DATA' ) ],
name=os.path.join('build\\pyi.win32\\electrum', cmdline_name + "-portable.exe"),
name=os.path.join('build\\pyi.win32\\electrum-lbry', cmdline_name + "-portable.exe"),
debug=False,
strip=None,
upx=False,
@ -145,7 +145,7 @@ exe_dependent = EXE(
pyz,
a.scripts,
exclude_binaries=True,
name=os.path.join('build\\pyi.win32\\electrum', cmdline_name),
name=os.path.join('build\\pyi.win32\\electrum-lbry', cmdline_name),
debug=False,
strip=None,
upx=False,

View file

@ -0,0 +1,34 @@
FROM ubuntu:18.04@sha256:5f4bdc3467537cbbe563e80db2c3ec95d548a9145d64453b06939c4592d67b6d
ENV LC_ALL=C.UTF-8 LANG=C.UTF-8
RUN dpkg --add-architecture i386 && \
apt-get update -q && \
apt-get install -qy \
wget=1.19.4-1ubuntu2.1 \
gnupg2=2.2.4-1ubuntu1.1 \
dirmngr=2.2.4-1ubuntu1.1 \
python3-software-properties=0.96.24.32.1 \
software-properties-common=0.96.24.32.1 \
&& \
wget -nc https://dl.winehq.org/wine-builds/Release.key && \
apt-key add Release.key && \
apt-add-repository https://dl.winehq.org/wine-builds/ubuntu/ && \
apt-get update -q && \
apt-get install -qy \
wine-stable-amd64:amd64=3.0.1~bionic \
wine-stable-i386:i386=3.0.1~bionic \
wine-stable:amd64=3.0.1~bionic \
winehq-stable:amd64=3.0.1~bionic \
git \
p7zip-full=16.02+dfsg-6 \
make=4.1-9.1ubuntu1 \
mingw-w64=5.0.3-1 \
autotools-dev=20180224.1 \
autoconf=2.69-11 \
libtool=2.4.6-2 \
gettext=0.19.8.1-6 \
&& \
rm -rf /var/lib/apt/lists/* && \
apt-get autoremove -y && \
apt-get clean

View file

@ -0,0 +1,103 @@
Deterministic Windows binaries with Docker
==========================================
Produced binaries are deterministic, so you should be able to generate
binaries that match the official releases.
This assumes an Ubuntu host, but it should not be too hard to adapt to another
similar system. The docker commands should be executed in the project's root
folder.
1. Install Docker
```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install -y docker-ce
```
2. Build image
```
$ sudo docker build --no-cache -t electrum-wine-builder-img contrib/build-wine/docker
```
Note: see [this](https://stackoverflow.com/a/40516974/7499128) if having dns problems
3. Build Windows binaries
It's recommended to build from a fresh clone
(but you can skip this if reproducibility is not necessary).
```
$ FRESH_CLONE=contrib/build-wine/fresh_clone && \
rm -rf $FRESH_CLONE && \
mkdir -p $FRESH_CLONE && \
cd $FRESH_CLONE && \
git clone https://github.com/spesmilo/electrum.git && \
cd electrum
```
And then build from this directory:
```
$ git checkout $REV
$ sudo docker run \
--name electrum-wine-builder-cont \
-v $PWD:/opt/wine64/drive_c/electrum \
--rm \
--workdir /opt/wine64/drive_c/electrum/contrib/build-wine \
electrum-wine-builder-img \
./build.sh
```
4. The generated binaries are in `./contrib/build-wine/dist`.
Note: the `setup` binary (NSIS installer) is not deterministic yet.
Code Signing
============
Electrum Windows builds are signed with a Microsoft Authenticode™ code signing
certificate in addition to the GPG-based signatures.
The advantage of using Authenticode is that Electrum users won't receive a
Windows SmartScreen warning when starting it.
The release signing procedure involves a signer (the holder of the
certificate/key) and one or multiple trusted verifiers:
| Signer | Verifier |
|-----------------------------------------------------------|-----------------------------------|
| Build .exe files using `build.sh` | |
| Sign .exe with `./sign.sh` | |
| Upload signed files to download server | |
| | Build .exe files using `build.sh` |
| | Compare files using `unsign.sh` |
| | Sign .exe file using `gpg -b` |
| Signer and verifiers: |
|-----------------------------------------------------------------------------------------------|
| Upload signatures to 'electrum-signatures' repo, as `$version/$filename.$builder.asc` |
Verify Integrity of signed binary
=================================
Every user can verify that the official binary was created from the source code in this
repository. To do so, the Authenticode signature needs to be stripped since the signature
is not reproducible.
This procedure removes the differences between the signed and unsigned binary:
1. Remove the signature from the signed binary using osslsigncode or signtool.
2. Set the COFF image checksum for the signed binary to 0x0. This is necessary
because pyinstaller doesn't generate a checksum.
3. Append null bytes to the _unsigned_ binary until the byte count is a multiple
of 8.
The script `unsign.sh` performs these steps.

View file

@ -2,11 +2,11 @@
;Include Modern UI
!include "TextFunc.nsh" ;Needed for the $GetSize function. I know, doesn't sound logical, it isn't.
!include "MUI2.nsh"
;--------------------------------
;Variables
!define PRODUCT_NAME "Electrum"
!define PRODUCT_NAME "LBRY_Wallet"
!define PRODUCT_WEB_SITE "https://github.com/spesmilo/electrum"
!define PRODUCT_PUBLISHER "Electrum Technologies GmbH"
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
@ -16,7 +16,7 @@
;Name and file
Name "${PRODUCT_NAME}"
OutFile "dist/electrum-setup.exe"
OutFile "dist/electrum-lbry-setup.exe"
;Default installation folder
InstallDir "$PROGRAMFILES\${PRODUCT_NAME}"
@ -29,31 +29,31 @@
;Specifies whether or not the installer will perform a CRC on itself before allowing an install
CRCCheck on
;Sets whether or not the details of the install are shown. Can be 'hide' (the default) to hide the details by default, allowing the user to view them, or 'show' to show them by default, or 'nevershow', to prevent the user from ever seeing them.
ShowInstDetails show
;Sets whether or not the details of the uninstall are shown. Can be 'hide' (the default) to hide the details by default, allowing the user to view them, or 'show' to show them by default, or 'nevershow', to prevent the user from ever seeing them.
ShowUninstDetails show
;Sets the colors to use for the install info screen (the default is 00FF00 000000. Use the form RRGGBB (in hexadecimal, as in HTML, only minus the leading '#', since # can be used for comments). Note that if "/windows" is specified as the only parameter, the default windows colors will be used.
InstallColors /windows
;This command sets the compression algorithm used to compress files/data in the installer. (http://nsis.sourceforge.net/Reference/SetCompressor)
SetCompressor /SOLID lzma
;Sets the dictionary size in megabytes (MB) used by the LZMA compressor (default is 8 MB).
SetCompressorDictSize 64
;Sets the text that is shown (by default it is 'Nullsoft Install System vX.XX') in the bottom of the install window. Setting this to an empty string ("") uses the default; to set the string to blank, use " " (a space).
BrandingText "${PRODUCT_NAME} Installer v${PRODUCT_VERSION}"
BrandingText "${PRODUCT_NAME} Installer v${PRODUCT_VERSION}"
;Sets what the titlebars of the installer will display. By default, it is 'Name Setup', where Name is specified with the Name command. You can, however, override it with 'MyApp Installer' or whatever. If you specify an empty string (""), the default will be used (you can however specify " " to achieve a blank string)
Caption "${PRODUCT_NAME}"
;Adds the Product Version on top of the Version Tab in the Properties of the file.
VIProductVersion 1.0.0.0
;VIAddVersionKey - Adds a field in the Version Tab of the File Properties. This can either be a field provided by the system or a user defined field.
VIAddVersionKey ProductName "${PRODUCT_NAME} Installer"
VIAddVersionKey Comments "The installer for ${PRODUCT_NAME}"
@ -63,7 +63,7 @@
VIAddVersionKey FileVersion ${PRODUCT_VERSION}
VIAddVersionKey ProductVersion ${PRODUCT_VERSION}
VIAddVersionKey InternalName "${PRODUCT_NAME} Installer"
VIAddVersionKey LegalTrademarks "${PRODUCT_NAME} is a trademark of ${PRODUCT_PUBLISHER}"
VIAddVersionKey LegalTrademarks "${PRODUCT_NAME} is a trademark of ${PRODUCT_PUBLISHER}"
VIAddVersionKey OriginalFilename "${PRODUCT_NAME}.exe"
;--------------------------------
@ -71,9 +71,9 @@
!define MUI_ABORTWARNING
!define MUI_ABORTWARNING_TEXT "Are you sure you wish to abort the installation of ${PRODUCT_NAME}?"
!define MUI_ICON "c:\electrum\electrum\gui\icons\electrum.ico"
;--------------------------------
;Pages
@ -108,7 +108,7 @@ Section
RMDir /r "$INSTDIR\*.*"
Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*"
;Files to pack into the installer
File /r "dist\electrum\*.*"
File "c:\electrum\electrum\gui\icons\electrum.ico"
@ -122,21 +122,23 @@ Section
;Create desktop shortcut
DetailPrint "Creating desktop shortcut..."
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" ""
CreateShortCut "$DESKTOP\${PRODUCT_NAME}.lnk" "$INSTDIR\electrum-lbry-${PRODUCT_VERSION}.exe" ""
;Create start-menu items
DetailPrint "Creating start-menu items..."
CreateDirectory "$SMPROGRAMS\${PRODUCT_NAME}"
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" "" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} Testnet.lnk" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" "--testnet" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME}.lnk" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" "" "$INSTDIR\electrum-lbry-${PRODUCT_VERSION}.exe" 0
CreateShortCut "$SMPROGRAMS\${PRODUCT_NAME}\${PRODUCT_NAME} Testnet.lnk" "$INSTDIR\electrum-${PRODUCT_VERSION}.exe" "--testnet" "$INSTDIR\electrum-lbry-${PRODUCT_VERSION}.exe" 0
;Links bitcoin: URI's to Electrum
WriteRegStr HKCU "Software\Classes\bitcoin" "" "URL:bitcoin Protocol"
WriteRegStr HKCU "Software\Classes\bitcoin" "URL Protocol" ""
WriteRegStr HKCU "Software\Classes\bitcoin" "DefaultIcon" "$\"$INSTDIR\electrum.ico, 0$\""
WriteRegStr HKCU "Software\Classes\bitcoin\shell\open\command" "" "$\"$INSTDIR\electrum-${PRODUCT_VERSION}.exe$\" $\"%1$\""
WriteRegStr HKCU "Software\Classes\bitcoin\shell\open\command" "" "$\"$INSTDIR\electrum-lbry-${PRODUCT_VERSION}.exe$\" $\"%1$\""
;Adds an uninstaller possibility to Windows Uninstall or change a program section
WriteRegStr HKCU "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)"
@ -166,8 +168,8 @@ Section "Uninstall"
Delete "$DESKTOP\${PRODUCT_NAME}.lnk"
Delete "$SMPROGRAMS\${PRODUCT_NAME}\*.*"
RMDir "$SMPROGRAMS\${PRODUCT_NAME}"
DeleteRegKey HKCU "Software\Classes\bitcoin"
DeleteRegKey HKCU "Software\Classes\lbc"
DeleteRegKey HKCU "Software\${PRODUCT_NAME}"
DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}"
SectionEnd

82
contrib/make_locale Normal file
View file

@ -0,0 +1,82 @@
#!/usr/bin/env python3
import os
import subprocess
import io
import zipfile
import requests
os.chdir(os.path.dirname(os.path.realpath(__file__)))
os.chdir('..')
cmd = "find electrum -type f -name '*.py' -o -name '*.kv'"
files = subprocess.check_output(cmd, shell=True)
with open("app.fil", "wb") as f:
f.write(files)
print("Found {} files to translate".format(len(files.splitlines())))
# Generate fresh translation template
if not os.path.exists('electrum/locale'):
os.mkdir('electrum/locale')
cmd = 'xgettext -s --from-code UTF-8 --language Python --no-wrap -f app.fil --output=electrum/locale/messages.pot'
print('Generate template')
os.system(cmd)
os.chdir('electrum')
crowdin_identifier = 'electrum'
crowdin_file_name = 'files[electrum-client/messages.pot]'
locale_file_name = 'locale/messages.pot'
crowdin_api_key = None
filename = os.path.expanduser('~/.crowdin_api_key')
if os.path.exists(filename):
with open(filename) as f:
crowdin_api_key = f.read().strip()
if "crowdin_api_key" in os.environ:
crowdin_api_key = os.environ["crowdin_api_key"]
if crowdin_api_key:
# Push to Crowdin
print('Push to Crowdin')
url = ('https://api.crowdin.com/api/project/' + crowdin_identifier + '/update-file?key=' + crowdin_api_key)
with open(locale_file_name, 'rb') as f:
files = {crowdin_file_name: f}
response = requests.request('POST', url, files=files)
print("", "update-file:", "-"*20, response.text, "-"*20, sep="\n")
# Build translations
print('Build translations')
response = requests.request('GET', 'https://api.crowdin.com/api/project/' + crowdin_identifier + '/export?key=' + crowdin_api_key)
print("", "export:", "-" * 20, response.text, "-" * 20, sep="\n")
# Download & unzip
print('Download translations')
s = requests.request('GET', 'https://crowdin.com/backend/download/project/' + crowdin_identifier + '.zip').content
zfobj = zipfile.ZipFile(io.BytesIO(s))
print('Unzip translations')
for name in zfobj.namelist():
if not name.startswith('electrum-client/locale'):
continue
if name.endswith('/'):
if not os.path.exists(name[16:]):
os.mkdir(name[16:])
else:
with open(name[16:], 'wb') as output:
output.write(zfobj.read(name))
# Convert .po to .mo
print('Installing')
for lang in os.listdir('locale'):
if lang.startswith('messages'):
continue
# Check LC_MESSAGES folder
mo_dir = 'locale/%s/LC_MESSAGES' % lang
if not os.path.exists(mo_dir):
os.mkdir(mo_dir)
cmd = 'msgfmt --output-file="%s/electrum.mo" "locale/%s/electrum.po"' % (mo_dir,lang)
print('Installing', lang)
os.system(cmd)

BIN
electrum.icns Normal file

Binary file not shown.

View file

@ -139,7 +139,7 @@ class BaseWizard(Logger):
('standard', _("Standard wallet")),
('2fa', _("Wallet with two-factor authentication")),
('multisig', _("Multi-signature wallet")),
('imported', _("Import Bitcoin addresses or private keys")),
('imported', _("Import LBRY Credits addresses or private keys")),
]
choices = [pair for pair in wallet_kinds if pair[0] in wallet_types]
self.choice_dialog(title=title, message=message, choices=choices, run_next=self.on_wallet_type)
@ -211,8 +211,8 @@ class BaseWizard(Logger):
def import_addresses_or_keys(self):
v = lambda x: keystore.is_address_list(x) or keystore.is_private_key_list(x, raise_on_error=True)
title = _("Import Bitcoin Addresses")
message = _("Enter a list of Bitcoin addresses (this will create a watching-only wallet), or a list of private keys.")
title = _("Import LBRY Credits Addresses")
message = _("Enter a list of LBRY Credits addresses (this will create a watching-only wallet), or a list of private keys.")
self.add_xpub_dialog(title=title, message=message, run_next=self.on_import,
is_valid=v, allow_multi=True, show_wif_help=True)
@ -393,14 +393,13 @@ class BaseWizard(Logger):
# There is no general standard for HD multisig.
# For legacy, this is partially compatible with BIP45; assumes index=0
# For segwit, a custom path is used, as there is no standard at all.
default_choice_idx = 2
default_choice_idx = 0
choices = [
('standard', 'legacy multisig (p2sh)', normalize_bip32_derivation("m/45'/0")),
('p2wsh-p2sh', 'p2sh-segwit multisig (p2wsh-p2sh)', purpose48_derivation(0, xtype='p2wsh-p2sh')),
('p2wsh', 'native segwit multisig (p2wsh)', purpose48_derivation(0, xtype='p2wsh')),
]
else:
default_choice_idx = 2
default_choice_idx = 0
choices = [
('standard', 'legacy (p2pkh)', bip44_derivation(0, bip43_purpose=44)),
('p2wpkh-p2sh', 'p2sh-segwit (p2wpkh-p2sh)', bip44_derivation(0, bip43_purpose=49)),
@ -625,11 +624,11 @@ class BaseWizard(Logger):
_("The type of addresses used by your wallet will depend on your seed."),
_("Segwit wallets use bech32 addresses, defined in BIP173."),
_("Please note that websites and other wallets may not support these addresses yet."),
_("Thus, you might want to keep using a non-segwit wallet in order to be able to receive bitcoins during the transition period.")
_("Thus, you might want to keep using a non-segwit wallet in order to be able to receive LBRY Credits during the transition period.")
])
if choices is None:
choices = [
('create_segwit_seed', _('Segwit')),
('create_standard_seed', _('Legacy')),
]
self.choice_dialog(title=title, message=message, choices=choices, run_next=self.run)

View file

@ -24,6 +24,9 @@ import os
import threading
from typing import Optional, Dict, Mapping, Sequence
import hashlib
import hmac
from . import util
from .bitcoin import hash_encode, int_to_hex, rev_hex
from .crypto import sha256d
@ -35,9 +38,10 @@ from .logging import get_logger, Logger
_logger = get_logger(__name__)
HEADER_SIZE = 80 # bytes
MAX_TARGET = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
HEADER_SIZE = 112 # bytes
MAX_TARGET = 0x0000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
GENESIS_BITS = 0x1f00ffff
N_TARGET_TIMESPAN = 150
class MissingHeader(Exception):
pass
@ -49,6 +53,7 @@ def serialize_header(header_dict: dict) -> str:
s = int_to_hex(header_dict['version'], 4) \
+ rev_hex(header_dict['prev_block_hash']) \
+ rev_hex(header_dict['merkle_root']) \
+ rev_hex(header_dict['claim_trie_root']) \
+ int_to_hex(int(header_dict['timestamp']), 4) \
+ int_to_hex(int(header_dict['bits']), 4) \
+ int_to_hex(int(header_dict['nonce']), 4)
@ -64,9 +69,10 @@ def deserialize_header(s: bytes, height: int) -> dict:
h['version'] = hex_to_int(s[0:4])
h['prev_block_hash'] = hash_encode(s[4:36])
h['merkle_root'] = hash_encode(s[36:68])
h['timestamp'] = hex_to_int(s[68:72])
h['bits'] = hex_to_int(s[72:76])
h['nonce'] = hex_to_int(s[76:80])
h['claim_trie_root'] = hash_encode(s[68:100])
h['timestamp'] = hex_to_int(s[100:104])
h['bits'] = hex_to_int(s[104:108])
h['nonce'] = hex_to_int(s[108:112])
h['block_height'] = height
return h
@ -77,10 +83,35 @@ def hash_header(header: dict) -> str:
header['prev_block_hash'] = '00'*32
return hash_raw_header(serialize_header(header))
def pow_hash_header(header: dict) -> str:
if header is None:
return '0' * 64
return hash_encode(PoWHash(bfh(serialize_header(header))))
def sha256(x):
return hashlib.sha256(x).digest()
def sha512(x):
return hashlib.sha512(x).digest()
def ripemd160(x):
h = hashlib.new('ripemd160')
h.update(x)
return h.digest()
def Hash(x):
return sha256(sha256(x))
def hash_raw_header(header: str) -> str:
return hash_encode(sha256d(bfh(header)))
def PoWHash(x):
r = sha512(Hash(x))
r1 = ripemd160(r[:len(r) // 2])
r2 = ripemd160(r[len(r) // 2:])
r3 = Hash(r1 + r2)
return r3
# key: blockhash hex at forkpoint
# the chain at some key is the best chain that includes the given hash
@ -282,35 +313,37 @@ class Blockchain(Logger):
self._size = os.path.getsize(p)//HEADER_SIZE if os.path.exists(p) else 0
@classmethod
def verify_header(cls, header: dict, prev_hash: str, target: int, expected_header_hash: str=None) -> None:
_hash = hash_header(header)
if expected_header_hash and expected_header_hash != _hash:
raise Exception("hash mismatches with expected: {} vs {}".format(expected_header_hash, _hash))
def verify_header(self, header: dict, prev_hash: str, target: int, bits: int, expected_header_hash: str=None) -> None:
_hash = pow_hash_header(header)
if expected_header_hash:
_hash2 = hash_header(header)
if expected_header_hash != _hash2:
raise Exception("hash mismatches with expected: {} vs {}".format(expected_header_hash, _hash2))
if prev_hash != header.get('prev_block_hash'):
raise Exception("prev hash mismatch: %s vs %s" % (prev_hash, header.get('prev_block_hash')))
if constants.net.TESTNET:
return
bits = cls.target_to_bits(target)
if bits != header.get('bits'):
raise Exception("bits mismatch: %s vs %s" % (bits, header.get('bits')))
block_hash_as_num = int.from_bytes(bfh(_hash), byteorder='big')
if block_hash_as_num > target:
raise Exception(f"insufficient proof of work: {block_hash_as_num} vs target {target}")
#if bits != header.get('bits'):
# raise Exception("bits mismatch: %s vs %s" % (bits, header.get('bits')))
#if int('0x' + _hash, 16) > target:
# raise Exception("insufficient proof of work: %s vs target %s" % (int('0x' + _hash, 16), target))
def verify_chunk(self, index: int, data: bytes) -> None:
num = len(data) // HEADER_SIZE
start_height = index * 2016
prev_hash = self.get_hash(start_height - 1)
target = self.get_target(index-1)
for i in range(num):
height = start_height + i
header = self.read_header(height - 1)
#bits, target = self.get_target2(height - 1, header)
try:
expected_header_hash = self.get_hash(height)
except MissingHeader:
expected_header_hash = None
raw_header = data[i*HEADER_SIZE : (i+1)*HEADER_SIZE]
header = deserialize_header(raw_header, index*2016 + i)
self.verify_header(header, prev_hash, target, expected_header_hash)
self.verify_header(header, prev_hash, 0, 0, expected_header_hash)
prev_hash = hash_header(header)
@with_lock
@ -507,18 +540,73 @@ class Blockchain(Logger):
bits = last.get('bits')
target = self.bits_to_target(bits)
nActualTimespan = last.get('timestamp') - first.get('timestamp')
nTargetTimespan = 14 * 24 * 60 * 60
nActualTimespan = max(nActualTimespan, nTargetTimespan // 4)
nActualTimespan = min(nActualTimespan, nTargetTimespan * 4)
new_target = min(MAX_TARGET, (target * nActualTimespan) // nTargetTimespan)
# not any target can be represented in 32 bits:
new_target = self.bits_to_target(self.target_to_bits(new_target))
return new_target
nTargetTimespan = 150
nModulatedTimespan = nTargetTimespan - (nActualTimespan - nTargetTimespan) / 8
nMinTimespan = nTargetTimespan - (nTargetTimespan / 8)
nMaxTimespan = nTargetTimespan + (nTargetTimespan / 2)
if nModulatedTimespan < nMinTimespan:
nModulatedTimespan = nMinTimespan
elif nModulatedTimespan > nMaxTimespan:
nModulatedTimespan = nMaxTimespan
bnOld = ArithUint256.SetCompact(bits)
bnNew = bnOld * nModulatedTimespan
# this doesn't work if it is nTargetTimespan even though that
# is what it looks like it should be based on reading the code
# in lbry.cpp
bnNew /= nModulatedTimespan
if bnNew > MAX_TARGET:
bnNew = ArithUint256(MAX_TARGET)
return bnNew.compact(), bnNew._value
def get_target2(self, index, last, chain='main'):
if index == -1:
return GENESIS_BITS, MAX_TARGET
if index == 0:
return GENESIS_BITS, MAX_TARGET
first = self.read_header(index-1)
assert last is not None, "Last shouldn't be none"
# bits to target
bits = last.get('bits')
# print_error("Last bits: ", bits)
self.check_bits(bits)
# new target
nActualTimespan = last.get('timestamp') - first.get('timestamp')
nTargetTimespan = N_TARGET_TIMESPAN
nModulatedTimespan = nTargetTimespan - (nActualTimespan - nTargetTimespan) / 8
nMinTimespan = nTargetTimespan - (nTargetTimespan / 8)
nMaxTimespan = nTargetTimespan + (nTargetTimespan / 2)
if nModulatedTimespan < nMinTimespan:
nModulatedTimespan = nMinTimespan
elif nModulatedTimespan > nMaxTimespan:
nModulatedTimespan = nMaxTimespan
bnOld = ArithUint256.SetCompact(bits)
bnNew = bnOld * nModulatedTimespan
# this doesn't work if it is nTargetTimespan even though that
# is what it looks like it should be based on reading the code
# in lbry.cpp
bnNew /= nModulatedTimespan
if bnNew > MAX_TARGET:
bnNew = ArithUint256(MAX_TARGET)
return bnNew.compact, bnNew._value
def check_bits(self, bits):
bitsN = (bits >> 24) & 0xff
assert 0x03 <= bitsN <= 0x1f, \
"First part of bits should be in [0x03, 0x1d], but it was {}".format(hex(bitsN))
bitsBase = bits & 0xffffff
assert 0x8000 <= bitsBase <= 0x7fffff, \
"Second part of bits should be in [0x8000, 0x7fffff] but it was {}".format(bitsBase)
@classmethod
def bits_to_target(cls, bits: int) -> int:
bitsN = (bits >> 24) & 0xff
if not (0x03 <= bitsN <= 0x1d):
if not (0x03 <= bitsN <= 0x1f):
raise Exception("First part of bits should be in [0x03, 0x1d]")
bitsBase = bits & 0xffffff
if not (0x8000 <= bitsBase <= 0x7fffff):
@ -573,25 +661,33 @@ class Blockchain(Logger):
def can_connect(self, header: dict, check_height: bool=True) -> bool:
if header is None:
return False
height = header['block_height']
if check_height and self.height() != height - 1:
print("cannot connect at height", height)
return False
if height == 0:
return hash_header(header) == constants.net.GENESIS
try:
prev_hash = self.get_hash(height - 1)
except:
return False
if prev_hash != header.get('prev_block_hash'):
return False
try:
target = self.get_target(height // 2016 - 1)
bits, target = self.get_target2(height, header)
except MissingHeader:
return False
try:
self.verify_header(header, prev_hash, target)
self.verify_header(header, prev_hash, target, bits)
except BaseException as e:
print(e)
return False
return True
def connect_chunk(self, idx: int, hexdata: str) -> bool:
@ -632,3 +728,83 @@ def can_connect(header: dict) -> Optional[Blockchain]:
if b.can_connect(header):
return b
return None
class ArithUint256:
# https://github.com/bitcoin/bitcoin/blob/master/src/arith_uint256.cpp
__slots__ = '_value', '_compact'
def __init__(self, value: int) -> None:
self._value = value
self._compact: Optional[int] = None
@classmethod
def SetCompact(cls, nCompact):
return (ArithUint256.from_compact(nCompact))
@classmethod
def from_compact(cls, compact) -> 'ArithUint256':
size = compact >> 24
word = compact & 0x007fffff
if size <= 3:
return cls(word >> 8 * (3 - size))
else:
return cls(word << 8 * (size - 3))
@property
def value(self) -> int:
return self._value
@property
def compact(self) -> int:
if self._compact is None:
self._compact = self._calculate_compact()
return self._compact
@property
def negative(self) -> int:
return self._calculate_compact(negative=True)
@property
def bits(self) -> int:
""" Returns the position of the highest bit set plus one. """
bits = bin(self._value)[2:]
for i, d in enumerate(bits):
if d:
return (len(bits) - i) + 1
return 0
@property
def low64(self) -> int:
return self._value & 0xffffffffffffffff
def _calculate_compact(self, negative=False) -> int:
size = (self.bits + 7) // 8
if size <= 3:
compact = self.low64 << 8 * (3 - size)
else:
compact = ArithUint256(self._value >> 8 * (size - 3)).low64
# The 0x00800000 bit denotes the sign.
# Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
if compact & 0x00800000:
compact >>= 8
size += 1
assert (compact & ~0x007fffff) == 0
assert size < 256
compact |= size << 24
if negative and compact & 0x007fffff:
compact |= 0x00800000
return compact
def __mul__(self, x):
# Take the mod because we are limited to an unsigned 256 bit number
return ArithUint256((self._value * x) % 2 ** 256)
def __truediv__(self, x):
return ArithUint256(int(self._value / x))
def __gt__(self, other):
return self._value > other
def __lt__(self, other):
return self._value < other

View file

@ -239,7 +239,7 @@ class Commands:
@command('')
async def restore(self, text, passphrase=None, password=None, encrypt_file=True, wallet_path=None):
"""Restore a wallet from text. Text can be a seed phrase, a master
public key, a master private key, a list of bitcoin addresses
public key, a master private key, a list of LBRY Credits addresses
or bitcoin private keys.
If you want to be prompted for an argument, type '?' or ':' (concealed)
"""
@ -667,7 +667,7 @@ class Commands:
@command('w')
async def setlabel(self, key, label, wallet: Abstract_Wallet = None):
"""Assign a label to an item. Item may be a bitcoin address or a
"""Assign a label to an item. Item may be a LBRY Credits address or a
transaction ID"""
wallet.set_label(key, label)
@ -1012,8 +1012,8 @@ def eval_bool(x: str) -> bool:
param_descriptions = {
'privkey': 'Private key. Type \'?\' to get a prompt.',
'destination': 'Bitcoin address, contact or alias',
'address': 'Bitcoin address',
'destination': 'LBRY Credits address, contact or alias',
'address': 'LBRY Credits address',
'seed': 'Seed phrase',
'txid': 'Transaction ID',
'pos': 'Position',
@ -1023,8 +1023,8 @@ param_descriptions = {
'pubkey': 'Public key',
'message': 'Clear text message. Use quotes if it contains spaces.',
'encrypted': 'Encrypted message',
'amount': 'Amount to be sent (in BTC). Type \'!\' to send the maximum available.',
'requested_amount': 'Requested amount (in BTC).',
'amount': 'Amount to be sent (in LBC). Type \'!\' to send the maximum available.',
'requested_amount': 'Requested amount (in LBC).',
'outputs': 'list of ["address", amount]',
'redeem_script': 'redeem script (hexadecimal)',
}
@ -1042,7 +1042,7 @@ command_options = {
'labels': ("-l", "Show the labels of listed addresses"),
'nocheck': (None, "Do not verify aliases"),
'imax': (None, "Maximum number of inputs"),
'fee': ("-f", "Transaction fee (absolute, in BTC)"),
'fee': ("-f", "Transaction fee (absolute, in LBC)"),
'feerate': (None, "Transaction fee rate (in sat/byte)"),
'from_addr': ("-F", "Source address (must be a wallet address; use sweep to spend from non-wallet address)."),
'from_coins': (None, "Source coins (must be in wallet; use sweep to spend from non-wallet address)."),
@ -1062,7 +1062,7 @@ command_options = {
'timeout': (None, "Timeout in seconds"),
'force': (None, "Create new address beyond gap limit, if no more addresses are available."),
'pending': (None, "Show only pending requests."),
'push_amount': (None, 'Push initial amount (in BTC)'),
'push_amount': (None, 'Push initial amount (in LBC)'),
'expired': (None, "Show only expired requests."),
'paid': (None, "Show only paid requests."),
'show_addresses': (None, "Show input and output addresses"),
@ -1106,10 +1106,10 @@ config_variables = {
'addrequest': {
'ssl_privkey': 'Path to your SSL private key, needed to sign the request.',
'ssl_chain': 'Chain of SSL certificates, needed for signed requests. Put your certificate at the top and the root CA at the end',
'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of bitcoin: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"',
'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of lbry credits: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"',
},
'listrequests':{
'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of bitcoin: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"',
'url_rewrite': 'Parameters passed to str.replace(), in order to create the r= part of lbry credits: URIs. Example: \"(\'file:///var/www/\',\'https://electrum.org/\')\"',
}
}
@ -1194,7 +1194,7 @@ def get_parser():
subparsers = parser.add_subparsers(dest='cmd', metavar='<command>')
# gui
parser_gui = subparsers.add_parser('gui', description="Run Electrum's Graphical User Interface.", help="Run GUI (default)")
parser_gui.add_argument("url", nargs='?', default=None, help="bitcoin URI (or bip70 file)")
parser_gui.add_argument("url", nargs='?', default=None, help="lbry credits URI (or bip70 file)")
parser_gui.add_argument("-g", "--gui", dest="gui", help="select graphical user interface", choices=['qt', 'kivy', 'text', 'stdio'])
parser_gui.add_argument("-m", action="store_true", dest="hide_gui", default=False, help="hide GUI on startup")
parser_gui.add_argument("-L", "--lang", dest="language", default=None, help="default language used in GUI")

View file

@ -26,6 +26,7 @@
import os
import json
BLOCKS_PER_CHUNK = 96
from .util import inv_dict
from . import bitcoin
@ -60,14 +61,14 @@ class AbstractNet:
class BitcoinMainnet(AbstractNet):
TESTNET = False
WIF_PREFIX = 0x80
ADDRTYPE_P2PKH = 0
ADDRTYPE_P2SH = 5
SEGWIT_HRP = "bc"
GENESIS = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f"
WIF_PREFIX = 0x1c
ADDRTYPE_P2PKH = 0x55
ADDRTYPE_P2SH = 0x7A
SEGWIT_HRP = "lbc"
GENESIS = "9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463"
DEFAULT_PORTS = {'t': '50001', 's': '50002'}
DEFAULT_SERVERS = read_json('servers.json', {})
CHECKPOINTS = read_json('checkpoints.json', [])
CHECKPOINTS = read_json('bullshit.json', [])
BLOCK_HEIGHT_FIRST_LIGHTNING_CHANNELS = 497000
XPRV_HEADERS = {
@ -86,7 +87,7 @@ class BitcoinMainnet(AbstractNet):
'p2wsh': 0x02aa7ed3, # Zpub
}
XPUB_HEADERS_INV = inv_dict(XPUB_HEADERS)
BIP44_COIN_TYPE = 0
BIP44_COIN_TYPE = 140
LN_REALM_BYTE = 0
LN_DNS_SEEDS = [
'nodes.lightning.directory.',
@ -100,7 +101,7 @@ class BitcoinTestnet(AbstractNet):
WIF_PREFIX = 0xef
ADDRTYPE_P2PKH = 111
ADDRTYPE_P2SH = 196
SEGWIT_HRP = "tb"
SEGWIT_HRP = "tlbc"
GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
DEFAULT_PORTS = {'t': '51001', 's': '51002'}
DEFAULT_SERVERS = read_json('servers_testnet.json', {})
@ -132,7 +133,7 @@ class BitcoinTestnet(AbstractNet):
class BitcoinRegtest(BitcoinTestnet):
SEGWIT_HRP = "bcrt"
SEGWIT_HRP = "blbc"
GENESIS = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206"
DEFAULT_SERVERS = read_json('servers_regtest.json', {})
CHECKPOINTS = []
@ -144,7 +145,7 @@ class BitcoinSimnet(BitcoinTestnet):
WIF_PREFIX = 0x64
ADDRTYPE_P2PKH = 0x3f
ADDRTYPE_P2SH = 0x7b
SEGWIT_HRP = "sb"
SEGWIT_HRP = "slbc"
GENESIS = "683e86bd5c6d110d91b94b97137ba6bfe02dbbdb8e3dff722a669b5d69d77af6"
DEFAULT_SERVERS = read_json('servers_regtest.json', {})
CHECKPOINTS = []

View file

@ -93,7 +93,7 @@ class Contacts(dict, Logger):
'type': 'openalias',
'validated': validated
}
raise Exception("Invalid Bitcoin address or alias", k)
raise Exception("Invalid LBRY Credits address or alias", k)
def resolve_openalias(self, url):
# support email-style addresses, per the OA standard
@ -103,7 +103,7 @@ class Contacts(dict, Logger):
except DNSException as e:
self.logger.info(f'Error resolving openalias: {repr(e)}')
return None
prefix = 'btc'
prefix = 'lbc'
for record in records:
string = to_string(record.strings[0], 'utf8')
if string.startswith('oa1:' + prefix):
@ -121,7 +121,7 @@ class Contacts(dict, Logger):
return regex.search(haystack).groups()[0]
except AttributeError:
return None
def _validate(self, data):
for k, v in list(data.items()):
if k == 'contacts':
@ -133,4 +133,3 @@ class Contacts(dict, Logger):
if _type != 'address':
data.pop(k)
return data

View file

@ -28,6 +28,7 @@
"BTC",
"BTN",
"BWP",
"BYN",
"BZD",
"CAD",
"CDF",
@ -46,6 +47,7 @@
"DZD",
"EGP",
"ETB",
"ETH",
"EUR",
"FJD",
"FKP",
@ -160,6 +162,7 @@
"XCD",
"XOF",
"XPF",
"XRP",
"YER",
"ZAR",
"ZMW",
@ -172,175 +175,6 @@
"Bitbank": [
"JPY"
],
"BitcoinAverage": [
"AED",
"AFN",
"ALL",
"AMD",
"ANG",
"AOA",
"ARS",
"AUD",
"AWG",
"AZN",
"BAM",
"BBD",
"BDT",
"BGN",
"BHD",
"BIF",
"BMD",
"BND",
"BOB",
"BRL",
"BSD",
"BTN",
"BWP",
"BYN",
"BZD",
"CAD",
"CDF",
"CHF",
"CLF",
"CLP",
"CNH",
"CNY",
"COP",
"CRC",
"CUC",
"CUP",
"CVE",
"CZK",
"DJF",
"DKK",
"DOP",
"DZD",
"EGP",
"ERN",
"ETB",
"EUR",
"FJD",
"FKP",
"GBP",
"GEL",
"GGP",
"GHS",
"GIP",
"GMD",
"GNF",
"GTQ",
"GYD",
"HKD",
"HNL",
"HRK",
"HTG",
"HUF",
"IDR",
"ILS",
"IMP",
"INR",
"IQD",
"IRR",
"ISK",
"JEP",
"JMD",
"JOD",
"JPY",
"KES",
"KGS",
"KHR",
"KMF",
"KPW",
"KRW",
"KWD",
"KYD",
"KZT",
"LAK",
"LBP",
"LKR",
"LRD",
"LSL",
"LYD",
"MAD",
"MDL",
"MGA",
"MKD",
"MMK",
"MNT",
"MOP",
"MRO",
"MUR",
"MVR",
"MWK",
"MXN",
"MYR",
"MZN",
"NAD",
"NGN",
"NIO",
"NOK",
"NPR",
"NZD",
"OMR",
"PAB",
"PEN",
"PGK",
"PHP",
"PKR",
"PLN",
"PYG",
"QAR",
"RON",
"RSD",
"RUB",
"RWF",
"SAR",
"SBD",
"SCR",
"SDG",
"SEK",
"SGD",
"SHP",
"SLL",
"SOS",
"SRD",
"SSP",
"STD",
"SVC",
"SYP",
"SZL",
"THB",
"TJS",
"TMT",
"TND",
"TOP",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
"UGX",
"USD",
"UYU",
"UZS",
"VES",
"VND",
"VUV",
"WST",
"XAF",
"XAG",
"XAU",
"XCD",
"XDR",
"XOF",
"XPD",
"XPF",
"XPT",
"YER",
"ZAR",
"ZMW",
"ZWL"
],
"BitcoinVenezuela": [
"ARS",
"ETH",
@ -350,9 +184,6 @@
"VEF",
"XMR"
],
"Bitcointoyou": [
"BRL"
],
"Bitso": [
"MXN"
],
@ -604,6 +435,7 @@
"THB",
"TRY",
"TWD",
"UAH",
"USD",
"VEF",
"VND",
@ -657,12 +489,14 @@
"CUC",
"CVE",
"CZK",
"DAI",
"DJF",
"DKK",
"DOP",
"DZD",
"EEK",
"EGP",
"EOS",
"ERN",
"ETB",
"ETC",
@ -733,6 +567,7 @@
"NPR",
"NZD",
"OMR",
"OXT",
"PAB",
"PEN",
"PGK",
@ -741,10 +576,12 @@
"PLN",
"PYG",
"QAR",
"REP",
"RON",
"RSD",
"RUB",
"RWF",
"SAI",
"SAR",
"SBD",
"SCR",
@ -773,6 +610,7 @@
"UYU",
"UZS",
"VEF",
"VES",
"VND",
"VUV",
"WST",
@ -781,10 +619,13 @@
"XAU",
"XCD",
"XDR",
"XLM",
"XOF",
"XPD",
"XPF",
"XPT",
"XRP",
"XTZ",
"YER",
"ZAR",
"ZEC",
@ -802,14 +643,14 @@
],
"LocalBitcoins": [
"AED",
"AMD",
"AOA",
"ARS",
"AUD",
"BAM",
"BDT",
"BGN",
"BOB",
"BRL",
"BWP",
"BYN",
"CAD",
"CHF",
@ -828,7 +669,6 @@
"GHS",
"GTQ",
"HKD",
"HNL",
"HRK",
"HUF",
"IDR",
@ -836,25 +676,26 @@
"INR",
"IRR",
"JOD",
"JPY",
"KES",
"KRW",
"KWD",
"KZT",
"LKR",
"LTC",
"MAD",
"MDL",
"MUR",
"MXN",
"MYR",
"NGN",
"NIO",
"NOK",
"NZD",
"OMR",
"PAB",
"PEN",
"PHP",
"PKR",
"PLN",
"QAR",
"PYG",
"RON",
"RSD",
"RUB",
@ -865,7 +706,6 @@
"SZL",
"THB",
"TRY",
"TTD",
"TWD",
"TZS",
"UAH",
@ -875,21 +715,15 @@
"VES",
"VND",
"XAF",
"XMR",
"XOF",
"XRP",
"ZAR"
],
"MercadoBitcoin": [
"BRL"
],
"NegocieCoins": [
"BRL"
"ZAR",
"ZMW"
],
"TheRockTrading": [
"EUR"
],
"Zaif": [
"JPY"
],
"itBit": []
}
]
}

View file

@ -352,7 +352,7 @@ POINT_AT_INFINITY = ECPubkey(None)
def msg_magic(message: bytes) -> bytes:
from .bitcoin import var_int
length = bfh(var_int(len(message)))
return b"\x18Bitcoin Signed Message:\n" + length + message
return b"\x18LBRYcrd Signed Message:\n" + length + message
def verify_signature(pubkey: bytes, sig: bytes, h: bytes) -> bool:

View file

@ -184,7 +184,7 @@ class ElectrumWindow(App):
def on_new_intent(self, intent):
data = intent.getDataString()
if intent.getScheme() == 'bitcoin':
if intent.getScheme() == 'lbrycredits':
self.set_URI(data)
elif intent.getScheme() == 'lightning':
self.set_ln_invoice(data)

View file

@ -0,0 +1,56 @@
#!python
#!/usr/bin/env python
from kivy.app import App
from kivy.uix.bubble import Bubble
from kivy.animation import Animation
from kivy.uix.floatlayout import FloatLayout
from kivy.lang import Builder
from kivy.factory import Factory
from kivy.clock import Clock
from electrum.gui.kivy.i18n import _
Builder.load_string('''
<MenuItem@Button>
background_normal: ''
background_color: (0.192, .498, 0.745, 1)
height: '48dp'
size_hint: 1, None
<ContextMenu>
size_hint: 1, None
height: '48dp'
pos: (0, 0)
show_arrow: False
arrow_pos: 'top_mid'
padding: 0
orientation: 'horizontal'
BoxLayout:
size_hint: 1, 1
height: '48dp'
padding: '12dp', '0dp'
spacing: '3dp'
orientation: 'horizontal'
id: buttons
''')
class MenuItem(Factory.Button):
pass
class ContextMenu(Bubble):
def __init__(self, obj, action_list):
Bubble.__init__(self)
self.obj = obj
for k, v in action_list:
l = MenuItem()
l.text = _(k)
def func(f=v):
Clock.schedule_once(lambda dt: f(obj), 0.15)
l.on_release = func
self.ids.buttons.add_widget(l)
def hide(self):
if self.parent:
self.parent.hide_menu()

View file

@ -0,0 +1,169 @@
from kivy.app import App
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from decimal import Decimal
Builder.load_string('''
<InvoicesLabel@Label>
#color: .305, .309, .309, 1
text_size: self.width, None
halign: 'left'
valign: 'top'
<InvoiceItem@CardItem>
requestor: ''
memo: ''
amount: ''
status: ''
date: ''
icon: 'atlas://electrum/gui/kivy/theming/light/important'
Image:
id: icon
source: root.icon
size_hint: None, 1
width: self.height *.54
mipmap: True
BoxLayout:
spacing: '8dp'
height: '32dp'
orientation: 'vertical'
Widget
InvoicesLabel:
text: root.requestor
shorten: True
Widget
InvoicesLabel:
text: root.memo
color: .699, .699, .699, 1
font_size: '13sp'
shorten: True
Widget
BoxLayout:
spacing: '8dp'
height: '32dp'
orientation: 'vertical'
Widget
InvoicesLabel:
text: root.amount
font_size: '15sp'
halign: 'right'
width: '110sp'
Widget
InvoicesLabel:
text: root.status
font_size: '13sp'
halign: 'right'
color: .699, .699, .699, 1
Widget
<InvoicesDialog@Popup>
id: popup
title: _('Invoices')
BoxLayout:
id: box
orientation: 'vertical'
spacing: '1dp'
ScrollView:
GridLayout:
cols: 1
id: invoices_container
size_hint: 1, None
height: self.minimum_height
spacing: '2dp'
padding: '12dp'
''')
from kivy.properties import BooleanProperty
from electrum.gui.kivy.i18n import _
from electrum.util import format_time
from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
from electrum.gui.kivy.uix.context_menu import ContextMenu
invoice_text = {
PR_UNPAID:_('Pending'),
PR_UNKNOWN:_('Unknown'),
PR_PAID:_('Paid'),
PR_EXPIRED:_('Expired')
}
pr_icon = {
PR_UNPAID: 'atlas://electrum/gui/kivy/theming/light/important',
PR_UNKNOWN: 'atlas://electrum/gui/kivy/theming/light/important',
PR_PAID: 'atlas://electrum/gui/kivy/theming/light/confirmed',
PR_EXPIRED: 'atlas://electrum/gui/kivy/theming/light/close'
}
class InvoicesDialog(Factory.Popup):
def __init__(self, app, screen, callback):
Factory.Popup.__init__(self)
self.app = app
self.screen = screen
self.callback = callback
self.cards = {}
self.context_menu = None
def get_card(self, pr):
key = pr.get_id()
ci = self.cards.get(key)
if ci is None:
ci = Factory.InvoiceItem()
ci.key = key
ci.screen = self
self.cards[key] = ci
ci.requestor = pr.get_requestor()
ci.memo = pr.get_memo()
amount = pr.get_amount()
if amount:
ci.amount = self.app.format_amount_and_units(amount)
status = self.app.wallet.invoices.get_status(ci.key)
ci.status = invoice_text[status]
ci.icon = pr_icon[status]
else:
ci.amount = _('No Amount')
ci.status = ''
exp = pr.get_expiration_date()
ci.date = format_time(exp) if exp else _('Never')
return ci
def update(self):
self.menu_actions = [('Pay', self.do_pay), ('Details', self.do_view), ('Delete', self.do_delete)]
invoices_list = self.ids.invoices_container
invoices_list.clear_widgets()
_list = self.app.wallet.invoices.sorted_list()
for pr in _list:
ci = self.get_card(pr)
invoices_list.add_widget(ci)
def do_pay(self, obj):
self.hide_menu()
self.dismiss()
pr = self.app.wallet.invoices.get(obj.key)
self.app.on_pr(pr)
def do_view(self, obj):
pr = self.app.wallet.invoices.get(obj.key)
pr.verify(self.app.wallet.contacts)
self.app.show_pr_details(pr.get_dict(), obj.status, True)
def do_delete(self, obj):
from .question import Question
def cb(result):
if result:
self.app.wallet.invoices.remove(obj.key)
self.hide_menu()
self.update()
d = Question(_('Delete invoice?'), cb)
d.open()
def show_menu(self, obj):
self.hide_menu()
self.context_menu = ContextMenu(obj, self.menu_actions)
self.ids.box.add_widget(self.context_menu)
def hide_menu(self):
if self.context_menu is not None:
self.ids.box.remove_widget(self.context_menu)
self.context_menu = None

View file

@ -0,0 +1,157 @@
from kivy.app import App
from kivy.factory import Factory
from kivy.properties import ObjectProperty
from kivy.lang import Builder
from decimal import Decimal
Builder.load_string('''
<RequestLabel@Label>
#color: .305, .309, .309, 1
text_size: self.width, None
halign: 'left'
valign: 'top'
<RequestItem@CardItem>
address: ''
memo: ''
amount: ''
status: ''
date: ''
icon: 'atlas://electrum/gui/kivy/theming/light/important'
Image:
id: icon
source: root.icon
size_hint: None, 1
width: self.height *.54
mipmap: True
BoxLayout:
spacing: '8dp'
height: '32dp'
orientation: 'vertical'
Widget
RequestLabel:
text: root.address
shorten: True
Widget
RequestLabel:
text: root.memo
color: .699, .699, .699, 1
font_size: '13sp'
shorten: True
Widget
BoxLayout:
spacing: '8dp'
height: '32dp'
orientation: 'vertical'
Widget
RequestLabel:
text: root.amount
halign: 'right'
font_size: '15sp'
Widget
RequestLabel:
text: root.status
halign: 'right'
font_size: '13sp'
color: .699, .699, .699, 1
Widget
<RequestsDialog@Popup>
id: popup
title: _('Requests')
BoxLayout:
id:box
orientation: 'vertical'
spacing: '1dp'
ScrollView:
GridLayout:
cols: 1
id: requests_container
size_hint: 1, None
height: self.minimum_height
spacing: '2dp'
padding: '12dp'
''')
from kivy.properties import BooleanProperty
from electrum.gui.kivy.i18n import _
from electrum.util import format_time
from electrum.paymentrequest import PR_UNPAID, PR_PAID, PR_UNKNOWN, PR_EXPIRED
from electrum.gui.kivy.uix.context_menu import ContextMenu
pr_icon = {
PR_UNPAID: 'atlas://electrum/gui/kivy/theming/light/important',
PR_UNKNOWN: 'atlas://electrum/gui/kivy/theming/light/important',
PR_PAID: 'atlas://electrum/gui/kivy/theming/light/confirmed',
PR_EXPIRED: 'atlas://electrum/gui/kivy/theming/light/close'
}
request_text = {
PR_UNPAID: _('Pending'),
PR_UNKNOWN: _('Unknown'),
PR_PAID: _('Received'),
PR_EXPIRED: _('Expired')
}
class RequestsDialog(Factory.Popup):
def __init__(self, app, screen, callback):
Factory.Popup.__init__(self)
self.app = app
self.screen = screen
self.callback = callback
self.cards = {}
self.context_menu = None
def get_card(self, req):
address = req['address']
ci = self.cards.get(address)
if ci is None:
ci = Factory.RequestItem()
ci.address = address
ci.screen = self
self.cards[address] = ci
amount = req.get('amount')
ci.amount = self.app.format_amount_and_units(amount) if amount else ''
ci.memo = req.get('memo', '')
status, conf = self.app.wallet.get_request_status(address)
ci.status = request_text[status]
ci.icon = pr_icon[status]
#exp = pr.get_expiration_date()
#ci.date = format_time(exp) if exp else _('Never')
return ci
def update(self):
self.menu_actions = [(_('Show'), self.do_show), (_('Delete'), self.do_delete)]
requests_list = self.ids.requests_container
requests_list.clear_widgets()
_list = self.app.wallet.get_sorted_requests(self.app.electrum_config)
for pr in _list:
ci = self.get_card(pr)
requests_list.add_widget(ci)
def do_show(self, obj):
self.hide_menu()
self.dismiss()
self.app.show_request(obj.address)
def do_delete(self, req):
from .question import Question
def cb(result):
if result:
self.app.wallet.remove_payment_request(req.address, self.app.electrum_config)
self.hide_menu()
self.update()
d = Question(_('Delete request'), cb)
d.open()
def show_menu(self, obj):
self.hide_menu()
self.context_menu = ContextMenu(obj, self.menu_actions)
self.ids.box.add_widget(self.context_menu)
def hide_menu(self):
if self.context_menu is not None:
self.ids.box.remove_widget(self.context_menu)
self.context_menu = None

View file

@ -0,0 +1,89 @@
#:import Decimal decimal.Decimal
Popup:
id: popup
is_invoice: True
amount: 0
requestor: ''
exp: ''
description: ''
status: ''
signature: ''
isaddr: ''
fund: 0
pk: ''
title: _('Invoice') if popup.is_invoice else _('Request')
tx_hash: ''
BoxLayout:
orientation: 'vertical'
ScrollView:
GridLayout:
cols: 1
height: self.minimum_height
size_hint_y: None
padding: '10dp'
spacing: '10dp'
GridLayout:
cols: 1
size_hint_y: None
height: self.minimum_height
spacing: '10dp'
BoxLabel:
text: (_('Status') if popup.amount or popup.is_invoice or popup.isaddr == 'y' else _('Amount received')) if root.status else ''
value: root.status
BoxLabel:
text: _('Request amount') if root.amount else ''
value: app.format_amount_and_units(root.amount) if root.amount else ''
BoxLabel:
text: _('Requestor') if popup.is_invoice else _('Address')
value: root.requestor
BoxLabel:
text: _('Signature') if root.signature else ''
value: root.signature
BoxLabel:
text: _('Expiration') if root.exp else ''
value: root.exp
BoxLabel:
text: _('Description') if root.description else ''
value: root.description
BoxLabel:
text: _('Balance') if popup.fund else ''
value: app.format_amount_and_units(root.fund) if root.fund else ''
TopLabel:
text: _('Private Key')
RefLabel:
id: pk_label
touched: True if not self.touched else True
data: root.pk
TopLabel:
text: _('Outputs') if popup.is_invoice else ''
OutputList:
id: output_list
TopLabel:
text: _('Transaction ID') if popup.tx_hash else ''
TxHashLabel:
data: popup.tx_hash
name: _('Transaction ID')
Widget:
size_hint: 1, 0.1
BoxLayout:
size_hint: 1, None
height: '48dp'
Widget:
size_hint: 0.5, None
height: '48dp'
Button:
size_hint: 2, None
height: '48dp'
text: _('Close')
on_release: popup.dismiss()
Button:
size_hint: 2, None
height: '48dp'
text: _('Hide private key') if pk_label.data else _('Export private key')
on_release:
setattr(pk_label, 'data', '') if pk_label.data else popup.export(pk_label, popup.requestor)

View file

@ -82,7 +82,7 @@ from .amountedit import AmountEdit, BTCAmountEdit, FreezableLineEdit, FeerateEdi
from .qrcodewidget import QRCodeWidget, QRDialog
from .qrtextedit import ShowQRTextEdit, ScanQRTextEdit
from .transaction_dialog import show_transaction
from .fee_slider import FeeSlider
#from .fee_slider import FeeSlider
from .util import (read_QIcon, ColorScheme, text_dialog, icon_path, WaitingDialog,
WindowModalDialog, ChoicesLayout, HelpLabel, Buttons,
OkButton, InfoButton, WWLabel, TaskThread, CancelButton,
@ -991,8 +991,8 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
msg = ' '.join([
_('Expiration date of your request.'),
_('This information is seen by the recipient if you send them a signed payment request.'),
_('Expired requests have to be deleted manually from your list, in order to free the corresponding Bitcoin addresses.'),
_('The bitcoin address never expires and will always be part of this electrum wallet.'),
_('Expired requests have to be deleted manually from your list, in order to free the corresponding LBRY Credits addresses.'),
_('The LBRY Credits address never expires and will always be part of this electrum wallet.'),
])
grid.addWidget(HelpLabel(_('Request expires'), msg), 2, 0)
grid.addWidget(self.expires_combo, 2, 1)
@ -1033,7 +1033,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
addr = str(self.receive_address_e.text())
self.receive_address_widgets.setVisible(bool(addr))
msg = _('Bitcoin address where the payment should be received. Note that each payment request uses a different Bitcoin address.')
msg = _('LBRY Credits address where the payment should be received. Note that each payment request uses a different LBRY Credits address.')
receive_address_label = HelpLabel(_('Receiving address'), msg)
self.receive_address_e = ButtonsTextEdit()
@ -1246,7 +1246,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
self.amount_e = BTCAmountEdit(self.get_decimal_point)
self.payto_e = PayToEdit(self)
msg = _('Recipient of the funds.') + '\n\n'\
+ _('You may enter a Bitcoin address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a Bitcoin address)')
+ _('You may enter a LBRY Credits address, a label from your list of contacts (a list of completions will be proposed), or an alias (email-like address that forwards to a LBRY Credits address)')
payto_label = HelpLabel(_('Pay to'), msg)
grid.addWidget(payto_label, 1, 0)
grid.addWidget(self.payto_e, 1, 1, 1, -1)
@ -2199,7 +2199,7 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
def show_mpk(index):
mpk_text.setText(mpk_list[index])
mpk_text.repaint() # macOS hack for #4777
# only show the combobox in case multiple accounts are available
if len(mpk_list) > 1:
# only show the combobox if multiple master keys are defined

View file

@ -445,8 +445,8 @@ class Interface(Logger):
self.logger.info(f'requesting block header {height} in mode {assert_mode}')
# use lower timeout as we usually have network.bhi_lock here
timeout = self.network.get_network_timeout_seconds(NetworkTimeout.Urgent)
res = await self.session.send_request('blockchain.block.header', [height], timeout=timeout)
return blockchain.deserialize_header(bytes.fromhex(res), height)
res = await self.session.send_request('blockchain.block.headers', [height,1], timeout=timeout)
return blockchain.deserialize_header(bytes.fromhex(res['hex']), height)
async def request_chunk(self, height: int, tip=None, *, can_return_early=False):
index = height // 2016
@ -518,10 +518,12 @@ class Interface(Logger):
async def run_fetch_blocks(self):
header_queue = asyncio.Queue()
await self.session.subscribe('blockchain.headers.subscribe', [], header_queue)
await self.session.subscribe('blockchain.headers.subscribe', [True], header_queue)
while True:
item = await header_queue.get()
raw_header = item[0]
print(item)
raw_header = item[1]
print(raw_header)
height = raw_header['height']
header = blockchain.deserialize_header(bfh(raw_header['hex']), height)
self.tip_header = header

99
electrum/jsonrpc.py Normal file
View file

@ -0,0 +1,99 @@
#!/usr/bin/env python3
#
# Electrum - lightweight Bitcoin client
# Copyright (C) 2018 Thomas Voegtlin
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from base64 import b64decode
import time
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer, SimpleJSONRPCRequestHandler
from . import util
class RPCAuthCredentialsInvalid(Exception):
def __str__(self):
return 'Authentication failed (bad credentials)'
class RPCAuthCredentialsMissing(Exception):
def __str__(self):
return 'Authentication failed (missing credentials)'
class RPCAuthUnsupportedType(Exception):
def __str__(self):
return 'Authentication failed (only basic auth is supported)'
# based on http://acooke.org/cute/BasicHTTPA0.html by andrew cooke
class VerifyingJSONRPCServer(SimpleJSONRPCServer):
def __init__(self, *args, rpc_user, rpc_password, **kargs):
self.rpc_user = rpc_user
self.rpc_password = rpc_password
class VerifyingRequestHandler(SimpleJSONRPCRequestHandler):
def parse_request(myself):
# first, call the original implementation which returns
# True if all OK so far
if SimpleJSONRPCRequestHandler.parse_request(myself):
# Do not authenticate OPTIONS-requests
if myself.command.strip() == 'OPTIONS':
return True
try:
self.authenticate(myself.headers)
return True
except (RPCAuthCredentialsInvalid, RPCAuthCredentialsMissing,
RPCAuthUnsupportedType) as e:
myself.send_error(401, str(e))
except BaseException as e:
import traceback, sys
traceback.print_exc(file=sys.stderr)
myself.send_error(500, str(e))
return False
SimpleJSONRPCServer.__init__(
self, requestHandler=VerifyingRequestHandler, *args, **kargs)
def authenticate(self, headers):
if self.rpc_password == '':
# RPC authentication is disabled
return
auth_string = headers.get('Authorization', None)
if auth_string is None:
raise RPCAuthCredentialsMissing()
(basic, _, encoded) = auth_string.partition(' ')
if basic != 'Basic':
raise RPCAuthUnsupportedType()
encoded = util.to_bytes(encoded, 'utf8')
credentials = util.to_string(b64decode(encoded), 'utf8')
(username, _, password) = credentials.partition(':')
if not (util.constant_time_compare(username, self.rpc_user)
and util.constant_time_compare(password, self.rpc_password)):
time.sleep(0.050)
raise RPCAuthCredentialsInvalid()

View file

@ -140,7 +140,7 @@ class Mnemonic(Logger):
mnemonic = normalize_text(mnemonic)
passphrase = passphrase or ''
passphrase = normalize_text(passphrase)
return hashlib.pbkdf2_hmac('sha512', mnemonic.encode('utf-8'), b'electrum' + passphrase.encode('utf-8'), iterations = PBKDF2_ROUNDS)
return hashlib.pbkdf2_hmac('sha512', mnemonic.encode('utf-8'), b'lbryum' + passphrase.encode('utf-8'), iterations = PBKDF2_ROUNDS)
def mnemonic_encode(self, i):
n = len(self.wordlist)

94
electrum/msqr.py Normal file
View file

@ -0,0 +1,94 @@
# from http://eli.thegreenplace.net/2009/03/07/computing-modular-square-roots-in-python/
def modular_sqrt(a, p):
""" Find a quadratic residue (mod p) of 'a'. p
must be an odd prime.
Solve the congruence of the form:
x^2 = a (mod p)
And returns x. Note that p - x is also a root.
0 is returned is no square root exists for
these a and p.
The Tonelli-Shanks algorithm is used (except
for some simple cases in which the solution
is known from an identity). This algorithm
runs in polynomial time (unless the
generalized Riemann hypothesis is false).
"""
# Simple cases
#
if legendre_symbol(a, p) != 1:
return 0
elif a == 0:
return 0
elif p == 2:
return p
elif p % 4 == 3:
return pow(a, (p + 1) // 4, p)
# Partition p-1 to s * 2^e for an odd s (i.e.
# reduce all the powers of 2 from p-1)
#
s = p - 1
e = 0
while s % 2 == 0:
s //= 2
e += 1
# Find some 'n' with a legendre symbol n|p = -1.
# Shouldn't take long.
#
n = 2
while legendre_symbol(n, p) != -1:
n += 1
# Here be dragons!
# Read the paper "Square roots from 1; 24, 51,
# 10 to Dan Shanks" by Ezra Brown for more
# information
#
# x is a guess of the square root that gets better
# with each iteration.
# b is the "fudge factor" - by how much we're off
# with the guess. The invariant x^2 = ab (mod p)
# is maintained throughout the loop.
# g is used for successive powers of n to update
# both a and b
# r is the exponent - decreases with each update
#
x = pow(a, (s + 1) // 2, p)
b = pow(a, s, p)
g = pow(n, s, p)
r = e
while True:
t = b
m = 0
for m in range(r):
if t == 1:
break
t = pow(t, 2, p)
if m == 0:
return x
gs = pow(g, 2 ** (r - m - 1), p)
g = (gs * gs) % p
x = (x * gs) % p
b = (b * g) % p
r = m
def legendre_symbol(a, p):
""" Compute the Legendre symbol a|p using
Euler's criterion. p is a prime, a is
relatively prime to p (if p divides
a, then a|p = 0)
Returns 1 if a has a square root modulo
p, -1 otherwise.
"""
ls = pow(a, (p - 1) // 2, p)
return -1 if ls == p - 1 else ls

View file

@ -117,7 +117,7 @@ def filter_noonion(servers):
return {k: v for k, v in servers.items() if not k.endswith('.onion')}
def filter_protocol(hostmap, protocol='s'):
def filter_protocol(hostmap, protocol='t'):
'''Filters the hostmap for those implementing protocol.
The result is a list in serialized form.'''
eligible = []
@ -128,7 +128,7 @@ def filter_protocol(hostmap, protocol='s'):
return eligible
def pick_random_server(hostmap=None, protocol='s', exclude_set=None):
def pick_random_server(hostmap=None, protocol='t', exclude_set=None):
if hostmap is None:
hostmap = constants.net.DEFAULT_SERVERS
if exclude_set is None:

View file

@ -0,0 +1,5 @@
from electrum.i18n import _
fullname = 'GreenAddress instant'
description = _("Allows validating if your transactions have instant confirmations by GreenAddress")
available_for = ['qt']

View file

@ -0,0 +1,106 @@
#!/usr/bin/env python
#
# Electrum - lightweight Bitcoin client
# Copyright (C) 2014 Thomas Voegtlin
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import base64
import urllib.parse
import sys
import requests
from PyQt5.QtWidgets import QApplication, QPushButton
from electrum.plugin import BasePlugin, hook
from electrum.i18n import _
class Plugin(BasePlugin):
button_label = _("Verify GA instant")
@hook
def transaction_dialog(self, d):
d.verify_button = QPushButton(self.button_label)
d.verify_button.clicked.connect(lambda: self.do_verify(d))
d.buttons.insert(0, d.verify_button)
self.transaction_dialog_update(d)
def get_my_addr(self, d):
"""Returns the address for given tx which can be used to request
instant confirmation verification from GreenAddress"""
for o in d.tx.outputs():
if d.wallet.is_mine(o.address):
return o.address
return None
@hook
def transaction_dialog_update(self, d):
if d.tx.is_complete() and self.get_my_addr(d):
d.verify_button.show()
else:
d.verify_button.hide()
def do_verify(self, d):
tx = d.tx
wallet = d.wallet
window = d.main_window
if wallet.is_watching_only():
d.show_critical(_('This feature is not available for watch-only wallets.'))
return
# 1. get the password and sign the verification request
password = None
if wallet.has_keystore_encryption():
msg = _('GreenAddress requires your signature \n'
'to verify that transaction is instant.\n'
'Please enter your password to sign a\n'
'verification request.')
password = window.password_dialog(msg, parent=d)
if not password:
return
try:
d.verify_button.setText(_('Verifying...'))
QApplication.processEvents() # update the button label
addr = self.get_my_addr(d)
message = "Please verify if %s is GreenAddress instant confirmed" % tx.txid()
sig = wallet.sign_message(addr, message, password)
sig = base64.b64encode(sig).decode('ascii')
# 2. send the request
response = requests.request("GET", ("https://greenaddress.it/verify/?signature=%s&txhash=%s" % (urllib.parse.quote(sig), tx.txid())),
headers = {'User-Agent': 'Electrum'})
response = response.json()
# 3. display the result
if response.get('verified'):
d.show_message(_('{} is covered by GreenAddress instant confirmation').format(tx.txid()), title=_('Verification successful!'))
else:
d.show_critical(_('{} is not covered by GreenAddress instant confirmation').format(tx.txid()), title=_('Verification failed!'))
except BaseException as e:
import traceback
traceback.print_exc(file=sys.stdout)
d.show_error(str(e))
finally:
d.verify_button.setText(self.button_label)

View file

@ -0,0 +1,11 @@
from trezorlib.client import proto, BaseClient, ProtocolMixin
from .clientbase import TrezorClientBase
class TrezorClient(TrezorClientBase, ProtocolMixin, BaseClient):
def __init__(self, transport, handler, plugin):
BaseClient.__init__(self, transport=transport)
ProtocolMixin.__init__(self, transport=transport)
TrezorClientBase.__init__(self, handler, plugin, proto)
TrezorClientBase.wrap_methods(TrezorClient)

View file

@ -0,0 +1,95 @@
from electrum.util import PrintError
class TrezorTransport(PrintError):
@staticmethod
def all_transports():
"""Reimplemented trezorlib.transport.all_transports so that we can
enable/disable specific transports.
"""
try:
# only to detect trezorlib version
from trezorlib.transport import all_transports
except ImportError:
# old trezorlib. compat for trezorlib < 0.9.2
transports = []
try:
from trezorlib.transport_bridge import BridgeTransport
transports.append(BridgeTransport)
except BaseException:
pass
try:
from trezorlib.transport_hid import HidTransport
transports.append(HidTransport)
except BaseException:
pass
try:
from trezorlib.transport_udp import UdpTransport
transports.append(UdpTransport)
except BaseException:
pass
try:
from trezorlib.transport_webusb import WebUsbTransport
transports.append(WebUsbTransport)
except BaseException:
pass
else:
# new trezorlib.
transports = []
try:
from trezorlib.transport.bridge import BridgeTransport
transports.append(BridgeTransport)
except BaseException:
pass
try:
from trezorlib.transport.hid import HidTransport
transports.append(HidTransport)
except BaseException:
pass
try:
from trezorlib.transport.udp import UdpTransport
transports.append(UdpTransport)
except BaseException:
pass
try:
from trezorlib.transport.webusb import WebUsbTransport
transports.append(WebUsbTransport)
except BaseException:
pass
return transports
return transports
def enumerate_devices(self):
"""Just like trezorlib.transport.enumerate_devices,
but with exception catching, so that transports can fail separately.
"""
devices = []
for transport in self.all_transports():
try:
new_devices = transport.enumerate()
except BaseException as e:
self.print_error('enumerate failed for {}. error {}'
.format(transport.__name__, str(e)))
else:
devices.extend(new_devices)
return devices
def get_transport(self, path=None):
"""Reimplemented trezorlib.transport.get_transport,
(1) for old trezorlib
(2) to be able to disable specific transports
(3) to call our own enumerate_devices that catches exceptions
"""
if path is None:
try:
return self.enumerate_devices()[0]
except IndexError:
raise Exception("No TREZOR device found") from None
def match_prefix(a, b):
return a.startswith(b) or b.startswith(a)
transports = [t for t in self.all_transports() if match_prefix(path, t.PATH_PREFIX)]
if transports:
return transports[0].find_by_path(path)
raise Exception("Unknown path prefix '%s'" % path)

47
electrum/scripts/util.py Normal file
View file

@ -0,0 +1,47 @@
import asyncio
from typing import List, Sequence
from aiorpcx import TaskGroup
from electrum.network import parse_servers, Network
from electrum.interface import Interface
#electrum.util.set_verbosity(True)
async def get_peers(network: Network):
while not network.is_connected():
await asyncio.sleep(1)
print("waiting for network to get connected...")
interface = network.interface
session = interface.session
print(f"asking server {interface.server} for its peers")
peers = parse_servers(await session.send_request('server.peers.subscribe'))
print(f"got {len(peers)} servers")
return peers
async def send_request(network: Network, servers: List[str], method: str, params: Sequence):
print(f"contacting {len(servers)} servers")
num_connecting = len(network.connecting)
for server in servers:
network._start_interface(server)
# sleep a bit
for _ in range(10):
if len(network.connecting) < num_connecting:
break
await asyncio.sleep(1)
print(f"connected to {len(network.interfaces)} servers. sending request to all.")
responses = dict()
async def get_response(iface: Interface):
try:
res = await iface.session.send_request(method, params, timeout=10)
except Exception as e:
print(f"server {iface.server} errored or timed out: ({repr(e)})")
res = e
responses[iface.server] = res
async with TaskGroup() as group:
for interface in network.interfaces.values():
await group.spawn(get_response(interface))
print("%d answers" % len(responses))
return responses

View file

@ -1,405 +1,14 @@
{
"3smoooajg7qqac2y.onion": {
"spv1.lbry.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
"version": "1.2"
},
"81-7-10-251.blue.kundencontroller.de": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"E-X.not.fyi": {
"lbryumx2.lbry.io": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"VPS.hsmiths.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"b.ooze.cc": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"bauerjda5hnedjam.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"bauerjhejlv6di7s.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"bitcoin.corgi.party": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"bitcoin3nqy3db7c.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"bitcoins.sk": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"btc.cihar.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"btc.xskyx.net": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"currentlane.lovebitco.in": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"daedalus.bauerj.eu": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.jochen-hoenicke.de": {
"pruning": "-",
"s": "50005",
"t": "50003",
"version": "1.4"
},
"dragon085.startdedicated.de": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"e-1.claudioboxx.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"e.keff.org": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum-server.ninja": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum-unlimited.criptolayer.net": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrum.eff.ro": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.festivaldelhumor.org": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.hsmiths.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.leblancnet.us": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.mindspot.org": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrum.qtornado.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.taborsky.cz": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrum.villocq.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum2.eff.ro": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum2.villocq.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrumx.bot.nu": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrumx.ddns.net": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrumx.ftp.sh": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrumx.soon.it": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrumxhqdsmlu.onion": {
"pruning": "-",
"t": "50001",
"version": "1.4"
},
"elx01.knas.systems": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"enode.duckdns.org": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"fedaykin.goip.de": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"fn.48.org": {
"pruning": "-",
"s": "50002",
"t": "50003",
"version": "1.4"
},
"helicarrier.bauerj.eu": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"hsmiths4fyqlw5xw.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"hsmiths5mjk6uijs.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.emzy.de": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"ndnd.selfhost.eu": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"ndndword5lpb7eex.onion": {
"pruning": "-",
"t": "50001",
"version": "1.4"
},
"orannis.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"ozahtqwp25chjdjd.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"qtornadoklbgdyww.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"rbx.curalle.ovh": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"s7clinmo4cazmhul.onion": {
"pruning": "-",
"t": "50001",
"version": "1.4"
},
"tardis.bauerj.eu": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"technetium.network": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"tomscryptos.com": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"ulrichard.ch": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"vmd27610.contaboserver.net": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"vmd30612.contaboserver.net": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"wsw6tua3xl24gsmi264zaep6seppjyrkyucpsmuxnjzyt3f3j6swshad.onion": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"xray587.startdedicated.de": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"yuio.top": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"bitcoin.dragon.zone": {
"pruning": "-",
"s": "50004",
"t": "50003",
"version": "1.4"
},
"ecdsa.net" : {
"pruning": "-",
"s": "110",
"t": "50001",
"version": "1.4"
},
"btc.usebsv.com": {
"pruning": "-",
"s": "50006",
"version": "1.4"
},
"e2.keff.org": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
},
"electrum.hodlister.co": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrum3.hodlister.co": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrum5.hodlister.co": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"electrumx.electricnewyear.net": {
"pruning": "-",
"s": "50002",
"version": "1.4"
},
"fortress.qtornado.com": {
"pruning": "-",
"s": "443",
"t": "50001",
"version": "1.4"
},
"green-gold.westeurope.cloudapp.azure.com": {
"pruning": "-",
"s": "56002",
"t": "56001",
"version": "1.4"
},
"electrumx.erbium.eu": {
"pruning": "-",
"s": "50002",
"t": "50001",
"version": "1.4"
"version": "1.2"
}
}

View file

@ -23,13 +23,12 @@ FEE_DEPTH_TARGETS = [10000000, 5000000, 2000000, 1000000, 500000, 200000, 100000
FEE_LN_ETA_TARGET = 2 # note: make sure the network is asking for estimates for this target
# satoshi per kbyte
FEERATE_MAX_DYNAMIC = 1500000
FEERATE_MAX_DYNAMIC = 50000
FEERATE_WARNING_HIGH_FEE = 600000
FEERATE_FALLBACK_STATIC_FEE = 150000
FEERATE_DEFAULT_RELAY = 1000
FEERATE_MAX_RELAY = 50000
FEERATE_STATIC_VALUES = [1000, 2000, 5000, 10000, 20000, 30000,
50000, 70000, 100000, 150000, 200000, 300000]
FEERATE_FALLBACK_STATIC_FEE = 50000
FEERATE_DEFAULT_RELAY = 50000
FEERATE_STATIC_VALUES = [50000,100000]
FEERATE_REGTEST_HARDCODED = 180000 # for eclair compat
@ -197,7 +196,7 @@ class SimpleConfig(Logger):
base_unit = self.user_config.get('base_unit')
if isinstance(base_unit, str):
self._set_key_in_user_config('base_unit', None)
map_ = {'btc':8, 'mbtc':5, 'ubtc':2, 'bits':2, 'sat':0}
map_ = {'lbc':8, 'mlbc':5, 'ulbc':2, 'lbcs':2, 'dewey':0}
decimal_point = map_.get(base_unit.lower())
self._set_key_in_user_config('decimal_point', decimal_point)

View file

@ -68,11 +68,11 @@ def inv_dict(d):
ca_path = certifi.where()
base_units = {'BTC':8, 'mBTC':5, 'bits':2, 'sat':0}
base_units = {'LBC':8, 'mLBC':5, 'deweys':2, 'dewey':0}
base_units_inverse = inv_dict(base_units)
base_units_list = ['BTC', 'mBTC', 'bits', 'sat'] # list(dict) does not guarantee order
base_units_list = ['LBC', 'mLBC', 'deweys', 'dewey'] # list(dict) does not guarantee order
DECIMAL_POINT_DEFAULT = 5 # mBTC
DECIMAL_POINT_DEFAULT = 8 # mBTC
# types of payment requests
PR_TYPE_ONCHAIN = 0
@ -554,9 +554,9 @@ def user_dir():
elif os.name == 'posix':
return os.path.join(os.environ["HOME"], ".electrum")
elif "APPDATA" in os.environ:
return os.path.join(os.environ["APPDATA"], "Electrum")
return os.path.join(os.environ["APPDATA"], "Electrum-lbry")
elif "LOCALAPPDATA" in os.environ:
return os.path.join(os.environ["LOCALAPPDATA"], "Electrum")
return os.path.join(os.environ["LOCALAPPDATA"], "Electrum-lbry")
else:
#raise Exception("No home directory found in environment variables.")
return
@ -721,39 +721,7 @@ def time_difference(distance_in_time, include_seconds):
return "over %d years" % (round(distance_in_minutes / 525600))
mainnet_block_explorers = {
'Bitupper Explorer': ('https://bitupper.com/en/explorer/bitcoin/',
{'tx': 'transactions/', 'addr': 'addresses/'}),
'Bitflyer.jp': ('https://chainflyer.bitflyer.jp/',
{'tx': 'Transaction/', 'addr': 'Address/'}),
'Blockchain.info': ('https://blockchain.com/btc/',
{'tx': 'tx/', 'addr': 'address/'}),
'blockchainbdgpzk.onion': ('https://blockchainbdgpzk.onion/',
{'tx': 'tx/', 'addr': 'address/'}),
'Blockstream.info': ('https://blockstream.info/',
{'tx': 'tx/', 'addr': 'address/'}),
'Bitaps.com': ('https://btc.bitaps.com/',
{'tx': '', 'addr': ''}),
'BTC.com': ('https://btc.com/',
{'tx': '', 'addr': ''}),
'Chain.so': ('https://www.chain.so/',
{'tx': 'tx/BTC/', 'addr': 'address/BTC/'}),
'Insight.is': ('https://insight.bitpay.com/',
{'tx': 'tx/', 'addr': 'address/'}),
'TradeBlock.com': ('https://tradeblock.com/blockchain/',
{'tx': 'tx/', 'addr': 'address/'}),
'BlockCypher.com': ('https://live.blockcypher.com/btc/',
{'tx': 'tx/', 'addr': 'address/'}),
'Blockchair.com': ('https://blockchair.com/bitcoin/',
{'tx': 'transaction/', 'addr': 'address/'}),
'blockonomics.co': ('https://www.blockonomics.co/',
{'tx': 'api/tx?txid=', 'addr': '#/search?q='}),
'OXT.me': ('https://oxt.me/',
{'tx': 'transaction/', 'addr': 'address/'}),
'smartbit.com.au': ('https://www.smartbit.com.au/',
{'tx': 'tx/', 'addr': 'address/'}),
'mynode.local': ('http://mynode.local:3002/',
{'tx': 'tx/', 'addr': 'address/'}),
'system default': ('blockchain:/',
'LBRY Explorer': ('https://explorer.lbry.io/',
{'tx': 'tx/', 'addr': 'address/'}),
}
@ -778,7 +746,7 @@ def block_explorer_info():
def block_explorer(config: 'SimpleConfig') -> str:
from . import constants
default_ = 'Blockstream.info'
default_ = 'LBRY Explorer'
be_key = config.get('block_explorer', default_)
be = block_explorer_info().get(be_key)
return be_key if be is not None else default_

View file

@ -1,7 +1,7 @@
ELECTRUM_VERSION = '4.0.0a0' # version of the client package
APK_VERSION = '4.0.0.0' # read by buildozer.spec
PROTOCOL_VERSION = '1.4' # protocol version requested
PROTOCOL_VERSION = '1.2' # protocol version requested
# The hash of the mnemonic seed must begin with this
SEED_PREFIX = '01' # Standard wallet

128
electrum/websockets.py Normal file
View file

@ -0,0 +1,128 @@
#!/usr/bin/env python
#
# Electrum - lightweight Bitcoin client
# Copyright (C) 2015 Thomas Voegtlin
#
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import threading
import os
import json
from collections import defaultdict
import asyncio
from typing import Dict, List, Tuple, TYPE_CHECKING
import traceback
import sys
try:
from SimpleWebSocketServer import WebSocket, SimpleSSLWebSocketServer
except ImportError:
sys.exit("install SimpleWebSocketServer")
from .util import PrintError
from . import bitcoin
from .synchronizer import SynchronizerBase
if TYPE_CHECKING:
from .network import Network
from .simple_config import SimpleConfig
request_queue = asyncio.Queue()
class ElectrumWebSocket(WebSocket, PrintError):
def handleMessage(self):
assert self.data[0:3] == 'id:'
self.print_error("message received", self.data)
request_id = self.data[3:]
asyncio.run_coroutine_threadsafe(
request_queue.put((self, request_id)), asyncio.get_event_loop())
def handleConnected(self):
self.print_error("connected", self.address)
def handleClose(self):
self.print_error("closed", self.address)
class BalanceMonitor(SynchronizerBase):
def __init__(self, config: 'SimpleConfig', network: 'Network'):
SynchronizerBase.__init__(self, network)
self.config = config
self.expected_payments = defaultdict(list) # type: Dict[str, List[Tuple[WebSocket, int]]]
def make_request(self, request_id):
# read json file
rdir = self.config.get('requests_dir')
n = os.path.join(rdir, 'req', request_id[0], request_id[1], request_id, request_id + '.json')
with open(n, encoding='utf-8') as f:
s = f.read()
d = json.loads(s)
addr = d.get('address')
amount = d.get('amount')
return addr, amount
async def main(self):
# resend existing subscriptions if we were restarted
for addr in self.expected_payments:
await self._add_address(addr)
# main loop
while True:
ws, request_id = await request_queue.get()
try:
addr, amount = self.make_request(request_id)
except Exception:
traceback.print_exc(file=sys.stderr)
continue
self.expected_payments[addr].append((ws, amount))
await self._add_address(addr)
async def _on_address_status(self, addr, status):
self.print_error('new status for addr {}'.format(addr))
sh = bitcoin.address_to_scripthash(addr)
balance = await self.network.get_balance_for_scripthash(sh)
for ws, amount in self.expected_payments[addr]:
if not ws.closed:
if sum(balance.values()) >= amount:
ws.sendMessage('paid')
class WebSocketServer(threading.Thread):
def __init__(self, config: 'SimpleConfig', network: 'Network'):
threading.Thread.__init__(self)
self.config = config
self.network = network
asyncio.set_event_loop(network.asyncio_loop)
self.daemon = True
self.balance_monitor = BalanceMonitor(self.config, self.network)
self.start()
def run(self):
asyncio.set_event_loop(self.network.asyncio_loop)
host = self.config.get('websocket_server')
port = self.config.get('websocket_port', 9999)
certfile = self.config.get('ssl_chain')
keyfile = self.config.get('ssl_privkey')
self.server = SimpleSSLWebSocketServer(host, port, ElectrumWebSocket, certfile, keyfile)
self.server.serveforever()

67
icons.qrc Normal file
View file

@ -0,0 +1,67 @@
<RCC>
<qresource prefix="/" >
<file>icons/electrum.png</file>
<file>icons/clock1.png</file>
<file>icons/clock2.png</file>
<file>icons/clock3.png</file>
<file>icons/clock4.png</file>
<file>icons/clock5.png</file>
<file>icons/confirmed.png</file>
<file>icons/copy.png</file>
<file>icons/digitalbitbox.png</file>
<file>icons/digitalbitbox_unpaired.png</file>
<file>icons/expired.png</file>
<file>icons/electrum_light_icon.png</file>
<file>icons/electrum_dark_icon.png</file>
<file>icons/electrumb.png</file>
<file>icons/eye1.png</file>
<file>icons/file.png</file>
<file>icons/info.png</file>
<file>icons/keepkey.png</file>
<file>icons/keepkey_unpaired.png</file>
<file>icons/key.png</file>
<file>icons/ledger.png</file>
<file>icons/ledger_unpaired.png</file>
<file>icons/lock.png</file>
<file>icons/microphone.png</file>
<file>icons/network.png</file>
<file>icons/offline_tx.png</file>
<file>icons/revealer.png</file>
<file>icons/revealer_c.png</file>
<file>icons/qrcode.png</file>
<file>icons/qrcode_white.png</file>
<file>icons/preferences.png</file>
<file>icons/safe-t_unpaired.png</file>
<file>icons/safe-t.png</file>
<file>icons/seed.png</file>
<file>icons/status_connected.png</file>
<file>icons/status_connected_fork.png</file>
<file>icons/status_connected_proxy.png</file>
<file>icons/status_connected_proxy_fork.png</file>
<file>icons/status_disconnected.png</file>
<file>icons/status_waiting.png</file>
<file>icons/status_lagging.png</file>
<file>icons/status_lagging_fork.png</file>
<file>icons/seal.png</file>
<file>icons/tab_addresses.png</file>
<file>icons/tab_coins.png</file>
<file>icons/tab_console.png</file>
<file>icons/tab_contacts.png</file>
<file>icons/tab_history.png</file>
<file>icons/tab_receive.png</file>
<file>icons/tab_send.png</file>
<file>icons/tor_logo.png</file>
<file>icons/speaker.png</file>
<file>icons/trezor_unpaired.png</file>
<file>icons/trezor.png</file>
<file>icons/coldcard.png</file>
<file>icons/coldcard_unpaired.png</file>
<file>icons/trustedcoin-status.png</file>
<file>icons/trustedcoin-wizard.png</file>
<file>icons/unconfirmed.png</file>
<file>icons/unpaid.png</file>
<file>icons/unlock.png</file>
<file>icons/warning.png</file>
<file>icons/zoom.png</file>
</qresource>
</RCC>

BIN
icons/clock1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
icons/clock2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
icons/clock3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
icons/clock4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
icons/clock5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
icons/coldcard.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 528 B

BIN
icons/coldcard_unpaired.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 B

BIN
icons/confirmed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

44
icons/confirmed.svg Normal file
View file

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<!-- https://commons.wikimedia.org/wiki/File:CrystalClearActionApply.svg -->
<svg width="512" height="512" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="linearGradient3930">
<stop style="stop-color:#ffffff;stop-opacity:1" offset="0"/>
<stop style="stop-color:#b3d187;stop-opacity:1" offset="0.53316939"/>
<stop style="stop-color:#28f400;stop-opacity:1" offset="1"/>
</linearGradient>
<linearGradient
id="linearGradient3904">
<stop style="stop-color:#4df60b;stop-opacity:1" offset="0"/>
<stop style="stop-color:#008000;stop-opacity:1" offset="1"/>
</linearGradient>
<linearGradient
id="linearGradient3878">
<stop style="stop-color:#79ef39;stop-opacity:1" offset="0"/>
<stop style="stop-color:#e9ffe3;stop-opacity:1" offset="1"/>
</linearGradient>
<linearGradient
id="linearGradient3044">
<stop style="stop-color:#f9ffd1;stop-opacity:1" offset="0"/>
<stop style="stop-color:#84e246;stop-opacity:1" offset="0.25998953"/>
<stop style="stop-color:#008000;stop-opacity:1" offset="1"/>
</linearGradient>
<radialGradient cx="60.764378" cy="104.22466" r="63.17857" fx="60.764378" fy="104.22466" id="radialGradient3838" xlink:href="#linearGradient3044" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.85744972,-0.78795737,0.89944031,0.97876469,-84.596269,34.939755)"/>
<radialGradient cx="145" cy="29" r="230" id="radialGradient3838-0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.66070117,-0.56004574,0.69392651,0.81864398,-39.045089,37.984063)">
<stop style="stop-color:#FFFFFF;stop-opacity:1" offset="0"/>
<stop style="stop-color:#FFFFFF;stop-opacity:1" offset="0.20"/>
<stop style="stop-color:#8BE456;stop-opacity:1" offset="0.51"/>
<stop style="stop-color:#8BE456;stop-opacity:1" offset="0.74"/>
<stop style="stop-color:#8BE456;stop-opacity:1" offset="1"/>
</radialGradient>
<radialGradient cx="48.356026" cy="122.04626" r="63.17857" fx="48.356026" fy="122.04626" id="radialGradient3838-4" xlink:href="#linearGradient3904" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.97494521,-0.22244513,0.1978519,0.86715661,-18.612993,12.209071)"/>
<radialGradient cx="57.965954" cy="109.5996" r="63.17857" fx="57.965954" fy="109.5996" id="radialGradient3838-5" xlink:href="#linearGradient3930" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0.77328328,-0.70601122,0.71173774,0.77955545,-64.080277,49.199946)"/>
</defs>
<g>
<path d="M 24.642857,32.642859 1.4285714,54.07143 51.071429,97.285716 126.78571,31.57143 l -22.5,-20 -52.142853,47.142858 z" id="path2997-1" style="fill:url(#radialGradient3838);fill-opacity:1;stroke:none"/>
<path d="M 1.4285714,54.428573 51.071429,97.64286 126.78571,31.928573 126.86922,40.559647 51.78571,108.71429 1.77525,63.026751 z" id="path2997-7" style="color:#000000;fill:url(#radialGradient3838-4);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"/>
<path d="m 24.285714,39.785715 27.5,25.000001 52.142856,-46.428569 15.71429,14.64285 c 0,0 -14.28571,12.857149 -28.928573,25.714289 -14.642854,12.85714 -54.642859,15 -80.7142871,-5.71429 C 20.357143,43.714286 24.285714,39.785715 24.285714,39.785715 z" id="path3042" style="color:#000000;fill:url(#radialGradient3838-0);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"/>
<path d="M 1.4285714,54.07143 51.071429,97.285716 126.78571,31.57143 51.071424,101.21429 z" id="path2997" style="color:#000000;fill:url(#radialGradient3838-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1px;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
icons/copy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
icons/digitalbitbox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
icons/electrum.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
icons/electrum.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
icons/electrum_launcher.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
icons/electrumb.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
icons/expired.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
icons/eye1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
icons/file.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
icons/info.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
icons/keepkey.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
icons/keepkey_unpaired.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
icons/key.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
icons/ledger.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
icons/ledger_unpaired.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

BIN
icons/lock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

277
icons/lock.svg Normal file
View file

@ -0,0 +1,277 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.0"
width="512"
height="512"
viewBox="0 0 22 22"
id="svg2">
<defs
id="defs4">
<linearGradient
id="linearGradient2411">
<stop
id="stop2413"
style="stop-color:#fee7b1;stop-opacity:1"
offset="0" />
<stop
id="stop2419"
style="stop-color:#ebd4b4;stop-opacity:1"
offset="0.25796592" />
<stop
id="stop2421"
style="stop-color:#c8a775;stop-opacity:1"
offset="0.50796592" />
<stop
id="stop2423"
style="stop-color:#b0935b;stop-opacity:1"
offset="0.74009573" />
<stop
id="stop2415"
style="stop-color:#fcebbf;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="6.72682"
y1="32.161697"
x2="40.938126"
y2="32.161697"
id="linearGradient2576"
xlink:href="#linearGradient2411"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.4857987,0,0,0.5667573,-0.657656,-4.7557638)" />
<linearGradient
id="linearGradient9845">
<stop
id="stop9847"
style="stop-color:white;stop-opacity:1"
offset="0" />
<stop
id="stop9849"
style="stop-color:white;stop-opacity:0.49484536"
offset="1" />
</linearGradient>
<linearGradient
x1="10.907269"
y1="25.002281"
x2="30.875446"
y2="36.127281"
id="linearGradient2573"
xlink:href="#linearGradient9845"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.4541292,0,0,0.5078849,0.107594,-1.9931168)" />
<linearGradient
id="linearGradient5881">
<stop
id="stop5883"
style="stop-color:#d6c8a7;stop-opacity:1"
offset="0" />
<stop
id="stop5885"
style="stop-color:#d0bd99;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="24.875"
y1="21"
x2="24.75"
y2="17"
id="linearGradient2570"
xlink:href="#linearGradient5881"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.4705882,0,0,0.807484,-0.294082,-6.1887078)" />
<linearGradient
id="linearGradient12071">
<stop
id="stop12073"
style="stop-color:white;stop-opacity:1"
offset="0" />
<stop
id="stop12075"
style="stop-color:white;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
x1="21.941509"
y1="21.550869"
x2="21.941509"
y2="18.037588"
id="linearGradient2567"
xlink:href="#linearGradient12071"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.4545455,0,0,0.2515938,0.090945,5.0971072)" />
<filter
x="-0.49411765"
y="-0.082352944"
width="1.9882354"
height="1.1647059"
color-interpolation-filters="sRGB"
id="filter5957">
<feGaussianBlur
id="feGaussianBlur5959"
stdDeviation="0.69878785" />
</filter>
<radialGradient
cx="15.9375"
cy="20.3125"
r="3.3125"
fx="15.9375"
fy="20.3125"
id="radialGradient2563"
xlink:href="#linearGradient6075"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7547171,0,0,0.3566673,-5.528266,1.0326108)" />
<linearGradient
id="linearGradient6075">
<stop
id="stop6077"
style="stop-color:black;stop-opacity:1"
offset="0" />
<stop
id="stop6079"
style="stop-color:black;stop-opacity:0"
offset="1" />
</linearGradient>
<radialGradient
cx="15.9375"
cy="20.3125"
r="3.3125"
fx="15.9375"
fy="20.3125"
id="radialGradient2560"
xlink:href="#linearGradient6075"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7547175,0,0,0.3566673,3.471729,1.0326108)" />
<linearGradient
id="linearGradient10591">
<stop
id="stop10593"
style="stop-color:#cad0c6;stop-opacity:1"
offset="0" />
<stop
id="stop10599"
style="stop-color:#eaece9;stop-opacity:1"
offset="0.5" />
<stop
id="stop10595"
style="stop-color:#c5cbc0;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="10.650842"
y1="2.9136841"
x2="27.192274"
y2="17.470011"
id="linearGradient2557"
xlink:href="#linearGradient10591"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.4093677,0,0,0.4456702,1.146515,-1.679622)" />
<linearGradient
x1="35.004684"
y1="14.849737"
x2="33.004314"
y2="14.849737"
id="linearGradient2580"
xlink:href="#linearGradient6227"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(1.6824037,1.125)" />
<filter
x="-0.24242526"
y="-0.047579072"
width="1.4848505"
height="1.0951581"
color-interpolation-filters="sRGB"
id="filter6251">
<feGaussianBlur
id="feGaussianBlur6253"
stdDeviation="0.24444548" />
</filter>
<linearGradient
id="linearGradient6227">
<stop
id="stop6229"
style="stop-color:black;stop-opacity:1"
offset="0" />
<stop
id="stop6231"
style="stop-color:black;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
x1="32.128025"
y1="13.789077"
x2="35.020981"
y2="13.789077"
id="linearGradient2578"
xlink:href="#linearGradient6227"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-19.532826,1.7437184)" />
<filter
color-interpolation-filters="sRGB"
id="filter5745">
<feGaussianBlur
id="feGaussianBlur5747"
stdDeviation="0.8362597" />
</filter>
</defs>
<g
id="layer1">
<path
d="m 3.585783,7.0017592 c 4.897701,-0.724037 9.847515,-0.611633 14.828433,0 0.601506,0 1.085748,0.523475 1.085748,1.173711 l 0,11.6979168 c 0,0.650237 -0.515495,1.079658 -1.085748,1.173711 -5.164043,0.60626 -9.5918631,0.601474 -14.828433,0 C 2.890521,20.827641 2.500036,20.523624 2.500036,19.873387 l 0,-11.6979168 c 0,-0.650236 0.484243,-1.173711 1.085747,-1.173711 z"
id="rect1314"
style="fill:url(#linearGradient2576);fill-opacity:1;fill-rule:evenodd;stroke:#a2824e;stroke-width:0.99999946;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0" />
<path
d="m 4.085707,8.5000012 13.828656,0 c 0.324462,0 0.585672,0.266352 0.585672,0.597203 l 0,10.3958448 c 0,0.33085 -0.231917,0.483593 -0.585672,0.597203 -4.521671,0.546964 -8.9847586,0.545698 -13.828656,0 -0.324462,-0.11361 -0.585671,-0.266353 -0.585671,-0.597203 l 0,-10.3958448 c 0,-0.330851 0.261209,-0.597203 0.585671,-0.597203 z"
id="rect6903"
style="opacity:0.37999998;fill:none;stroke:url(#linearGradient2573);stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.60109289;stroke-dashoffset:0" />
<path
d="m 3.779465,7.5385202 c 4.8137134,-0.786353 9.627427,-0.646293 14.441141,0 0.431803,0 0.77943,0.386003 0.77943,0.865475 l 0,1.498987 c 0,0.4794728 -0.347627,0.8654758 -0.77943,0.8654758 -5.023394,0.371496 -9.6453579,0.238912 -14.441141,0 -0.431804,0 -0.779429,-0.386003 -0.779429,-0.8654758 l 0,-1.498987 c 0,-0.479472 0.347625,-0.865475 0.779429,-0.865475 z"
id="rect1460"
style="fill:url(#linearGradient2570);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible" />
<path
d="m 4.045579,9.4999992 13.908915,0 c 0.30223,0 0.545542,0.129295 0.545542,0.289899 l 0,0.174986 c 0,0.1606028 -0.243312,0.2898978 -0.545542,0.2898978 -4.593039,0.317179 -9.2379615,0.33659 -13.908915,0 -0.302231,0 -0.545543,-0.129295 -0.545543,-0.2898978 l 0,-0.174986 c 0,-0.160604 0.243312,-0.289899 0.545543,-0.289899 z"
id="rect1593"
style="opacity:0.6;fill:none;stroke:url(#linearGradient2567);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
<rect
width="2.8284271"
height="16.970562"
rx="1.6077254"
ry="1.6077254"
x="14.594036"
y="23.226137"
transform="matrix(0.923405,0,0,0.5777374,-8.226979,-3.3564678)"
id="rect5887"
style="opacity:0.2;fill:white;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5957);enable-background:accumulate" />
<path
d="m 9.0000359,8.2774169 c 0,0.6525027 -1.1192909,1.1814597 -2.4999999,1.1814597 -1.380712,0 -2.5,-0.528957 -2.5,-1.1814597 0,-0.6525037 1.119288,-1.1814615 2.5,-1.1814615 1.380709,0 2.4999999,0.5289578 2.4999999,1.1814615 z"
id="path6073"
style="opacity:0.3;fill:url(#radialGradient2563);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
d="m 18.000036,8.2774169 c 0,0.6525027 -1.119288,1.1814597 -2.500001,1.1814597 -1.380712,0 -2.499999,-0.528957 -2.499999,-1.1814597 0,-0.6525037 1.119287,-1.1814615 2.499999,-1.1814615 1.380713,0 2.500001,0.5289578 2.500001,1.1814615 z"
id="path6083"
style="opacity:0.3;fill:url(#radialGradient2560);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
d="m 5.502269,8.1969323 0,-2.55585 c 0,-3.5074844 2.152214,-5.17378339 5.477269,-5.1299805 3.343147,0.0438029 5.518265,1.5812319 5.518265,5.1299805 l 0,2.6672674 c 0,0.8709416 -2.247715,0.98179 -2.247715,0 l 0,-1.7759272 c 0,-0.8913402 0.232705,-3.7756533 -3.247128,-3.7756533 -3.45114,0 -3.19968,2.9020879 -3.186298,3.7720995 l 0,1.6830728 c 0,1.0493847 -2.314393,1.0449226 -2.314393,-0.015009 z"
id="path2086"
style="fill:url(#linearGradient2557);fill-opacity:1;fill-rule:evenodd;stroke:#888a85;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 34.687087,10.837069 1.263948,0.125 c 0.927239,2.822733 0.736052,9.510413 0.736052,9.510413 -0.0625,1.125 -2.03125,0.53125 -2,0 l 0,-9.635413 z"
transform="matrix(0.4093677,0,0,0.4456703,1.146515,-0.8211368)"
id="rect1345"
style="opacity:0.18235294;fill:url(#linearGradient2580);fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter6251)" />
<path
d="m 12.926606,11.544175 0.371719,0.169195 c 1.720331,1.054966 2.173532,9.37783 2.173532,9.37783 -0.0625,1.125 -2.03125,0.53125 -2,0 0,0 0.37822,-6.87064 -0.545251,-9.547025 z"
transform="matrix(-0.4093677,0,0,0.4456703,13.04224,-1.0968812)"
id="path6332"
style="opacity:0.14117647;fill:url(#linearGradient2578);fill-opacity:1;fill-rule:evenodd;stroke:none;filter:url(#filter6251)" />
<path
d="m 13.876557,17.722122 0.124999,-7.5 c 0,-9.8763728 18.6875,-10.6764 18.6875,0.875 l 0,6.875"
transform="matrix(0.459148,0,0,0.4456703,-0.021657,0.2462079)"
id="path5675"
style="opacity:0.62352941;fill:none;stroke:white;stroke-width:4.42126894;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter5745);enable-background:accumulate" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

BIN
icons/microphone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

BIN
icons/network.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

BIN
icons/offline_tx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

BIN
icons/preferences.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

686
icons/preferences.svg Normal file
View file

@ -0,0 +1,686 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:ns="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512px"
height="512px"
id="svg4289"
sodipodi:version="0.32"
inkscape:version="0.45"
sodipodi:docbase="https://commons.wikimedia.org/wiki/File:Gnome-preferences-system.svg"
sodipodi:docname="preferences-system.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
viewBox="0 0 48 48">
<defs
id="defs4291">
<linearGradient
inkscape:collect="always"
id="linearGradient6998">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop7000" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop7002" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5443">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5445" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5447" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5437">
<stop
style="stop-color:#2e3436;stop-opacity:1"
offset="0"
id="stop5439" />
<stop
style="stop-color:#729fcf;stop-opacity:1"
offset="1"
id="stop5441" />
</linearGradient>
<linearGradient
id="linearGradient6791">
<stop
id="stop6793"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop6795"
offset="1"
style="stop-color:#ffffff;stop-opacity:0" />
</linearGradient>
<linearGradient
id="linearGradient6707">
<stop
id="stop6709"
offset="0"
style="stop-color:#888a85;stop-opacity:1" />
<stop
id="stop6711"
offset="1"
style="stop-color:#555753;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6696">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6698" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop6700" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6576">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6578" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop6580" />
</linearGradient>
<linearGradient
id="linearGradient6545">
<stop
style="stop-color:#d3d7cf;stop-opacity:1"
offset="0"
id="stop6547" />
<stop
style="stop-color:#eeeeec;stop-opacity:1"
offset="1"
id="stop6549" />
</linearGradient>
<linearGradient
id="linearGradient6525">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop6527" />
<stop
style="stop-color:#babdb6;stop-opacity:1"
offset="1"
id="stop6529" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6424">
<stop
style="stop-color:#eeeeec;stop-opacity:1"
offset="0"
id="stop6426" />
<stop
style="stop-color:#eeeeec;stop-opacity:0;"
offset="1"
id="stop6428" />
</linearGradient>
<linearGradient
id="linearGradient5440">
<stop
id="stop5442"
offset="0"
style="stop-color:#eeeeec;stop-opacity:1" />
<stop
id="stop5444"
offset="1"
style="stop-color:#a2a298;stop-opacity:1;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5402">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop5404" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop5406" />
</linearGradient>
<linearGradient
id="linearGradient2808">
<stop
id="stop2810"
offset="0"
style="stop-color:white;stop-opacity:1;" />
<stop
id="stop2812"
offset="1"
style="stop-color:white;stop-opacity:0.2937853" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient6221">
<stop
style="stop-color:black;stop-opacity:1;"
offset="0"
id="stop6223" />
<stop
style="stop-color:black;stop-opacity:0;"
offset="1"
id="stop6225" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5220">
<stop
style="stop-color:#0c1d35;stop-opacity:1"
offset="0"
id="stop5222" />
<stop
style="stop-color:white;stop-opacity:0.2937853"
offset="1"
id="stop5224" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient5210">
<stop
style="stop-color:#729fcf;stop-opacity:1"
offset="0"
id="stop5212" />
<stop
style="stop-color:#295ead;stop-opacity:1"
offset="1"
id="stop5214" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6221"
id="radialGradient6819"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.982963,0,0,0.508943,0.37414,16.84139)"
cx="21.96048"
cy="34.498356"
fx="21.96048"
fy="34.498356"
r="12.727922" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6221"
id="radialGradient6821"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.982963,0,0,0.508943,0.37414,16.84139)"
cx="21.96048"
cy="34.498356"
fx="21.96048"
fy="34.498356"
r="12.727922" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6545"
id="linearGradient6823"
gradientUnits="userSpaceOnUse"
x1="101.75"
y1="16.75"
x2="84.875"
y2="23.5" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6707"
id="linearGradient6825"
gradientUnits="userSpaceOnUse"
x1="101.76143"
y1="23.366385"
x2="84.3106"
y2="40.943737" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6791"
id="linearGradient6827"
gradientUnits="userSpaceOnUse"
x1="99.686363"
y1="7.6145449"
x2="75.039978"
y2="16.260931" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6525"
id="linearGradient6829"
gradientUnits="userSpaceOnUse"
x1="94"
y1="43.240894"
x2="94"
y2="40.766018" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5437"
id="linearGradient6831"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.9982232,0,0,1.1271997,101.97505,-16.992011)"
x1="-5.7610831"
y1="40.212852"
x2="-12.691682"
y2="44.514675" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6576"
id="linearGradient6833"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-58.460697,73.506628)"
x1="93.686363"
y1="11.614545"
x2="96.311363"
y2="3.2395456" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6696"
id="linearGradient6835"
gradientUnits="userSpaceOnUse"
x1="19.5"
y1="17.750786"
x2="19.5"
y2="7.8089299"
gradientTransform="translate(-1,-1)" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6221"
id="radialGradient6837"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.982963,0,0,0.508943,0.37414,16.84139)"
cx="21.96048"
cy="34.498356"
fx="21.96048"
fy="34.498356"
r="12.727922" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6221"
id="radialGradient6839"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.982963,0,0,0.508943,0.37414,16.84139)"
cx="21.96048"
cy="34.498356"
fx="21.96048"
fy="34.498356"
r="12.727922" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient6998"
id="radialGradient7004"
cx="24.32572"
cy="24.577896"
fx="24.32572"
fy="24.577896"
r="5.140625"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7495432,-0.7495432,1.8567518,1.8567518,-40.477603,-2.5737503)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5210"
id="linearGradient7047"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.8213511,0,0,1.0094537,61.676283,-5.2539543)"
x1="-10.69499"
y1="41.105709"
x2="-1.0492263"
y2="41.137775" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5443"
id="linearGradient7049"
gradientUnits="userSpaceOnUse"
x1="53.58926"
y1="32.856834"
x2="69.976395"
y2="44.960426" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5440"
id="linearGradient7051"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.7118239,-0.7118239,0.7071068,0.7071068,20.979979,22.298119)"
x1="24.518135"
y1="22.429499"
x2="25.910631"
y2="23.831284" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2808"
id="linearGradient7053"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.581783,0,0,0.6787466,57.543659,10.506054)"
x1="-6.9787297"
y1="37.126617"
x2="-9.9043236"
y2="36.848248" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5220"
id="linearGradient7055"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.4887947,0,0,0.6787448,59.055567,10.472634)"
x1="-8.9375"
y1="40.375"
x2="-7"
y2="40.375" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5402"
id="linearGradient7057"
gradientUnits="userSpaceOnUse"
x1="57.349243"
y1="37.496914"
x2="59.350101"
y2="37.505516" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient6424"
id="linearGradient7059"
gradientUnits="userSpaceOnUse"
x1="54.5"
y1="1.7340142"
x2="54.5"
y2="7.1931787" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666"
borderopacity="0.31372549"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="40.725752"
inkscape:cy="9.5969463"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:grid-bbox="false"
inkscape:document-units="px"
inkscape:window-width="897"
inkscape:window-height="925"
inkscape:window-x="88"
inkscape:window-y="25"
inkscape:showpageshadow="false"
gridspacingx="0.5px"
gridspacingy="0.5px"
gridempspacing="2"
inkscape:grid-points="false"
showguides="true"
inkscape:guide-bbox="true"
showborder="true">
<inkscape:grid
type="xygrid"
id="grid5999" />
</sodipodi:namedview>
<metadata
id="metadata4294">
<rdf:RDF>
<ns:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>System Preferences</dc:title>
<dc:creator>
<ns:Agent>
<dc:title>Andreas Nilsson</dc:title>
</ns:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>category</rdf:li>
<rdf:li>system</rdf:li>
<rdf:li>preferences</rdf:li>
<rdf:li>settings</rdf:li>
<rdf:li>control center</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:contributor>
<ns:Agent>
<dc:title>Jakub Steiner
Ulisse Perusin</dc:title>
</ns:Agent>
</dc:contributor>
<ns:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
</ns:Work>
<ns:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<ns:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<ns:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<ns:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<ns:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<ns:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<ns:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</ns:License>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Preferences</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Andreas Nilsson</dc:title>
</cc:Agent>
</dc:creator>
<dc:contributor>
<cc:Agent>
<dc:title>Lapo Calamandrei, Ulisse Perusin, Jakub Steiner</dc:title>
</cc:Agent>
</dc:contributor>
<cc:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:subject>
<rdf:Bag>
<rdf:li>category</rdf:li>
<rdf:li>system</rdf:li>
<rdf:li>preferences</rdf:li>
<rdf:li>settings</rdf:li>
<rdf:li>control center</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<path
sodipodi:type="arc"
style="opacity:0.15;fill:url(#radialGradient6839);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path5331"
sodipodi:cx="21.743534"
sodipodi:cy="34.299805"
sodipodi:rx="12.727922"
sodipodi:ry="6.3639612"
d="M 34.471457 34.299805 A 12.727922 6.3639612 0 1 1 9.0156116,34.299805 A 12.727922 6.3639612 0 1 1 34.471457 34.299805 z"
transform="matrix(0.9035244,0,0,0.6241817,-8.1457785,20.562958)" />
<path
sodipodi:type="arc"
style="opacity:0.2;fill:url(#radialGradient6837);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path6769"
sodipodi:cx="21.743534"
sodipodi:cy="34.299805"
sodipodi:rx="12.727922"
sodipodi:ry="6.3639612"
d="M 34.471457 34.299805 A 12.727922 6.3639612 0 1 1 9.0156116,34.299805 A 12.727922 6.3639612 0 1 1 34.471457 34.299805 z"
transform="matrix(0.3535525,0,0,0.2357023,2.8125306,34.415459)" />
<g
id="g6432"
transform="matrix(0.7071068,0.7071068,-0.7071068,0.7071068,0.4039197,-30.117395)">
<rect
transform="matrix(0.9999917,-4.085772e-3,-2.7048962e-3,0.9999963,0,0)"
ry="3.6587055"
rx="4.0743828"
y="27.726946"
x="50.588039"
height="17.996519"
width="8.9973431"
id="rect5288"
style="fill:url(#linearGradient7047);fill-opacity:1;stroke:#204a87;stroke-width:1.0000124;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
transform="matrix(0.9999873,-5.0480452e-3,-2.8992949e-3,0.9999958,0,0)"
ry="2.5968282"
rx="3.0795631"
y="28.815769"
x="51.574001"
height="15.960262"
width="7.0178103"
id="rect5292"
style="opacity:0.5;fill:none;fill-opacity:1;stroke:url(#linearGradient7049);stroke-width:1.00001645;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccccc"
id="path5286"
d="M 52.246834,0.49999993 L 52.604531,5.4548034 L 53.59322,7.162543 L 53.585977,28.755101 C 53.674365,30.257703 56.419206,30.336084 56.595983,28.745094 L 56.621068,7.1748733 L 57.628707,5.8770552 L 57.95997,0.51454306 C 57.95997,0.51454306 52.246834,0.49999993 52.246834,0.49999993 z "
style="fill:url(#linearGradient7051);fill-opacity:1;stroke:#888a85;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="opacity:0.3;fill:url(#linearGradient7053);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect2804"
width="1.4200811"
height="10.612979"
x="51.725819"
y="32.225933"
rx="0.6661315"
ry="1.6036282"
transform="matrix(0.9999908,-4.299452e-3,-4.299452e-3,0.9999908,0,0)" />
<rect
transform="matrix(0.9999869,-5.11738e-3,-3.6122511e-3,0.9999935,0,0)"
ry="1.6036212"
rx="1.3473127"
y="32.192463"
x="54.167618"
height="10.859921"
width="1.9551785"
id="rect5290"
style="opacity:0.3;fill:url(#linearGradient7055);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="opacity:0.25;fill:url(#linearGradient7057);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect5398"
width="1.420082"
height="10.612979"
x="57.132236"
y="32.24918"
rx="0.6661315"
ry="1.603629"
transform="matrix(0.9999908,-4.2994573e-3,-4.2994573e-3,0.9999908,0,0)" />
<path
sodipodi:nodetypes="ccccccccc"
id="path5450"
d="M 52.78125,1 L 53.09375,5.3125 L 54.03125,6.90625 C 54.073567,6.982692 54.095116,7.0688875 54.09375,7.15625 L 56.125,7.1875 C 56.120433,7.0757816 56.153441,6.9657558 56.21875,6.875 L 57.125,5.65625 L 57.4375,1 C 56.652768,1 53.565982,1 52.78125,1 z "
style="fill:url(#linearGradient7059);fill-opacity:1;stroke:none;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1" />
</g>
<path
style="opacity:0.5;fill:url(#radialGradient7004);fill-opacity:1;stroke:none;stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 25.96875,19.46875 L 18.46875,26.96875 L 21.25,29.75 L 28.75,22.25 L 25.96875,19.46875 z "
id="path6010" />
<g
id="g6807"
transform="translate(-1,0)">
<path
transform="matrix(0.8642397,0,0,0.6241817,18.208399,20.562958)"
d="M 34.471457 34.299805 A 12.727922 6.3639612 0 1 1 9.0156116,34.299805 A 12.727922 6.3639612 0 1 1 34.471457 34.299805 z"
sodipodi:ry="6.3639612"
sodipodi:rx="12.727922"
sodipodi:cy="34.299805"
sodipodi:cx="21.743534"
id="path6765"
style="opacity:0.15;fill:url(#radialGradient6819);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:type="arc" />
<path
transform="matrix(0.3535525,0,0,0.2357023,29.812531,34.415459)"
d="M 34.471457 34.299805 A 12.727922 6.3639612 0 1 1 9.0156116,34.299805 A 12.727922 6.3639612 0 1 1 34.471457 34.299805 z"
sodipodi:ry="6.3639612"
sodipodi:rx="12.727922"
sodipodi:cy="34.299805"
sodipodi:cx="21.743534"
id="path6773"
style="opacity:0.2;fill:url(#radialGradient6821);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:type="arc" />
<g
transform="translate(-1.697983,0.2707704)"
id="g6739">
<g
id="g6553"
transform="matrix(0.7071068,-0.7071068,0.7071068,0.7071068,-57.460697,74.506628)">
<path
sodipodi:nodetypes="csccsccscccccc"
id="path6491"
d="M 91,1.1482865 C 88.356663,2.3083638 86.5,4.9532014 86.5,8.0232865 C 86.5,10.894407 88.12854,13.387995 90.5,14.648286 L 90.5,43.414214 C 90.5,45.353214 92.061,46.914213 94,46.914214 C 95.939,46.914214 97.5,45.353213 97.5,43.414214 L 97.5,14.648286 C 99.87146,13.387995 101.5,10.894407 101.5,8.0232865 C 101.5,4.9532011 99.643337,2.3083637 97,1.1482865 L 97,7.0857865 L 95.28125,9.0857865 L 92.71875,9.0857865 L 91,7.0857865 L 91,1.1482865 z "
style="opacity:1;fill:url(#linearGradient6823);fill-opacity:1;stroke:url(#linearGradient6825);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.7;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscccscccscccccccccc"
id="path6505"
d="M 89.96875,2.9920365 C 88.491165,4.1803215 87.53125,5.9777353 87.53125,8.0232865 C 87.53125,10.510038 88.917637,12.651991 90.96875,13.742036 C 91.312399,13.913596 91.530012,14.264195 91.53125,14.648286 L 91.53125,43.414214 C 91.53125,44.807674 92.606539,45.882963 94,45.882964 C 95.39346,45.882964 96.46875,44.807673 96.46875,43.414214 L 96.46875,14.648286 C 96.469988,14.264195 96.687601,13.913596 97.03125,13.742036 C 99.082363,12.651991 100.46875,10.510038 100.46875,8.0232865 C 100.46875,5.977735 99.508835,4.1803214 98.03125,2.9920365 L 98.03125,7.0857865 C 98.028519,7.3272888 97.939894,7.5599296 97.78125,7.7420365 L 96.0625,9.7420365 C 95.871073,9.9773335 95.584572,10.114853 95.28125,10.117036 L 92.71875,10.117036 C 92.415428,10.114853 92.128927,9.9773335 91.9375,9.7420365 L 90.21875,7.7420365 C 90.060106,7.5599296 89.971481,7.3272888 89.96875,7.0857865 L 89.96875,2.9920365 z "
style="opacity:1;fill:none;fill-opacity:1;stroke:url(#linearGradient6827);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.7;stroke-opacity:1" />
<path
transform="translate(-3.7626907e-8,0.9142136)"
d="M 95.5 42.5 A 1.5 1.5 0 1 1 92.5,42.5 A 1.5 1.5 0 1 1 95.5 42.5 z"
sodipodi:ry="1.5"
sodipodi:rx="1.5"
sodipodi:cy="42.5"
sodipodi:cx="94"
id="path6507"
style="opacity:1;fill:#888a85;fill-opacity:1;stroke:url(#linearGradient6829);stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.7;stroke-opacity:1"
sodipodi:type="arc" />
<rect
style="opacity:0.23106061;fill:url(#linearGradient6831);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;display:inline"
id="rect6533"
width="3.9928944"
height="21.999802"
x="91.992836"
y="16.963778"
rx="1.7379364"
ry="1.7444341"
transform="matrix(0.9999999,3.8645919e-4,3.8358553e-4,0.9999999,0,0)" />
</g>
<path
style="fill:none;fill-opacity:1;stroke:url(#linearGradient6833);stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0.7;stroke-opacity:1"
d="M 13.973556,7.3037539 L 16.868274,10.198472 C 17.037111,10.371171 17.138946,10.598341 17.155536,10.839288 L 17.35441,13.468841 C 17.385431,13.770581 17.280086,14.070409 17.067148,14.286434 L 15.255187,16.098395 C 15.039162,16.311332 14.739334,16.416678 14.437595,16.385657 L 11.808041,16.186783 C 11.567094,16.170192 11.339925,16.068358 11.167226,15.899521 L 8.2725073,13.004802"
id="path6573"
sodipodi:nodetypes="cccccccccc" />
<path
style="opacity:0.59051723;fill:url(#linearGradient6835);fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0.7;stroke-opacity:1"
d="M 14.71875,6.8125 C 14.129935,6.8140249 13.543329,6.8880281 12.96875,7.03125 L 16.5,10.5625 C 16.589624,10.650873 16.646088,10.749545 16.65625,10.875 L 16.875,13.5 C 16.888638,13.656013 16.830347,13.827626 16.71875,13.9375 L 15.125,15.5625 C 17.279079,16.073694 19.038866,17.020591 21.34375,15.78125 C 22.074648,13.392376 21.483569,10.671069 19.59375,8.78125 C 18.245921,7.4334204 16.485196,6.8079254 14.71875,6.8125 z M 8,12 C 7.6061401,13.580092 7.7314214,15.26324 8.4375,16.75 C 9.564272,16.068398 10.560695,15.675078 11.46875,15.46875 L 8,12 z "
id="path6651"
sodipodi:nodetypes="ccccccccsccccc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 26 KiB

BIN
icons/qrcode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 314 B

BIN
icons/qrcode_white.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

BIN
icons/revealer.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 B

BIN
icons/revealer_c.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
icons/safe-t.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

BIN
icons/safe-t_unpaired.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
icons/seal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

BIN
icons/seed.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

BIN
icons/speaker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

BIN
icons/status_connected.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

173
icons/status_connected.svg Normal file
View file

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.0"
id="svg7854"
height="512"
width="512"
viewBox="9 9 30 30">
<defs
id="defs7856">
<linearGradient
id="linearGradient860">
<stop
id="stop856"
offset="0"
style="stop-color:#90bb65;stop-opacity:1" />
<stop
id="stop858"
offset="1"
style="stop-color:#6ac017;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient7577">
<stop
id="stop7579"
offset="0"
style="stop-color:#000000;stop-opacity:0.3137255;" />
<stop
id="stop7581"
offset="1"
style="stop-color:#ffffff;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient5167">
<stop
style="stop-color:#76d717;stop-opacity:1"
offset="0"
id="stop5169" />
<stop
style="stop-color:#509e07;stop-opacity:1"
offset="1"
id="stop5171" />
</linearGradient>
<linearGradient
id="linearGradient5184">
<stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop5186" />
<stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop5188" />
</linearGradient>
<linearGradient
gradientTransform="matrix(2.1074616,0,0,2.1078593,-9.43551,-10.006786)"
y2="17.024479"
x2="16.657505"
y1="10.883683"
x1="15.011773"
gradientUnits="userSpaceOnUse"
id="linearGradient8317"
xlink:href="#linearGradient7577" />
<radialGradient
gradientTransform="matrix(1.897257,0,0,1.897615,-6.10046,-6.6146433)"
r="7.5896134"
fy="20.410854"
fx="15.865708"
cy="20.410854"
cx="15.865708"
gradientUnits="userSpaceOnUse"
id="radialGradient8319"
xlink:href="#linearGradient5167" />
<radialGradient
r="5.96875"
fy="11.308558"
fx="14.05685"
cy="11.308558"
cx="14.05685"
gradientTransform="matrix(-4.2002315,0.5953403,0.2958442,2.0989386,75.31118,-18.732928)"
gradientUnits="userSpaceOnUse"
id="radialGradient8321"
xlink:href="#linearGradient5184" />
<linearGradient
gradientTransform="matrix(1.7591324,0,0,1.7580929,-3.90899,-4.3562887)"
y2="26.431587"
x2="13.458839"
y1="2.0178134"
x1="8.9317284"
gradientUnits="userSpaceOnUse"
id="linearGradient8323"
xlink:href="#linearGradient860" />
</defs>
<metadata
id="metadata7859">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Lapo Calamandrei</dc:title>
</cc:Agent>
</dc:creator>
<dc:source />
<cc:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:title></dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>record</rdf:li>
<rdf:li>media</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:contributor>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1">
<ellipse
ry="14.997972"
rx="14.995141"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:url(#linearGradient8317);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.11079514;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path7691"
cx="24.00086"
cy="24.002029" />
<ellipse
ry="13.502028"
rx="13.49948"
cy="24.002029"
cx="24.000866"
id="path7968"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient8319);fill-opacity:1;fill-rule:nonzero;stroke:#336402;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
<path
id="path7970"
d="M 25.3861,13.485003 C 20.31979,12.724926 15.45183,15.857848 14,20.764516 c 1.18871,3.18039 3.90811,5.70993 7.46677,6.47724 5.29459,1.141602 10.50115,-2.027543 12.01505,-7.143895 -1.18869,-3.180413 -3.90812,-5.709952 -7.46675,-6.477239 -0.217,-0.04678 -0.41248,-0.103152 -0.62897,-0.135619 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.404;fill:url(#radialGradient8321);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.09465754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
<ellipse
ry="12.509292"
rx="12.516688"
cy="24.009293"
cx="24.000891"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.54494413;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient8323);stroke-width:1.00000215;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path7972" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

View file

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.0"
id="svg7854"
height="512"
width="512"
viewBox="9 9 30 30">
<defs
id="defs7856">
<linearGradient
id="linearGradient860">
<stop
id="stop856"
offset="0"
style="stop-color:#479fc6;stop-opacity:1" />
<stop
id="stop858"
offset="1"
style="stop-color:#0c89c1;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient7577">
<stop
id="stop7579"
offset="0"
style="stop-color:#000000;stop-opacity:0.3137255;" />
<stop
id="stop7581"
offset="1"
style="stop-color:#ffffff;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient5167">
<stop
style="stop-color:#0090ef;stop-opacity:1"
offset="0"
id="stop5169" />
<stop
style="stop-color:#0062b2;stop-opacity:1"
offset="1"
id="stop5171" />
</linearGradient>
<linearGradient
id="linearGradient5184">
<stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop5186" />
<stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop5188" />
</linearGradient>
<linearGradient
gradientTransform="matrix(2.1074616,0,0,2.1078593,-9.43551,-10.006786)"
y2="17.024479"
x2="16.657505"
y1="10.883683"
x1="15.011773"
gradientUnits="userSpaceOnUse"
id="linearGradient8317"
xlink:href="#linearGradient7577" />
<radialGradient
gradientTransform="matrix(1.897257,0,0,1.897615,-6.10046,-6.6146433)"
r="7.5896134"
fy="20.410854"
fx="15.865708"
cy="20.410854"
cx="15.865708"
gradientUnits="userSpaceOnUse"
id="radialGradient8319"
xlink:href="#linearGradient5167" />
<radialGradient
r="5.96875"
fy="11.308558"
fx="14.05685"
cy="11.308558"
cx="14.05685"
gradientTransform="matrix(-4.2002315,0.5953403,0.2958442,2.0989386,75.31118,-18.732928)"
gradientUnits="userSpaceOnUse"
id="radialGradient8321"
xlink:href="#linearGradient5184" />
<linearGradient
gradientTransform="matrix(1.7591324,0,0,1.7580929,-3.90899,-4.3562887)"
y2="26.431587"
x2="13.458839"
y1="2.0178134"
x1="8.9317284"
gradientUnits="userSpaceOnUse"
id="linearGradient8323"
xlink:href="#linearGradient860" />
</defs>
<metadata
id="metadata7859">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Lapo Calamandrei</dc:title>
</cc:Agent>
</dc:creator>
<dc:source />
<cc:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:title></dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>record</rdf:li>
<rdf:li>media</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:contributor>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1">
<ellipse
ry="14.997972"
rx="14.995141"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:url(#linearGradient8317);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.11079514;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path7691"
cx="24.00086"
cy="24.002029" />
<ellipse
ry="13.502028"
rx="13.49948"
cy="24.002029"
cx="24.000866"
id="path7968"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient8319);fill-opacity:1;fill-rule:nonzero;stroke:#003f70;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
<path
id="path7970"
d="M 25.3861,13.485003 C 20.31979,12.724926 15.45183,15.857848 14,20.764516 c 1.18871,3.18039 3.90811,5.70993 7.46677,6.47724 5.29459,1.141602 10.50115,-2.027543 12.01505,-7.143895 -1.18869,-3.180413 -3.90812,-5.709952 -7.46675,-6.477239 -0.217,-0.04678 -0.41248,-0.103152 -0.62897,-0.135619 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.404;fill:url(#radialGradient8321);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.09465754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
<ellipse
ry="12.509292"
rx="12.516688"
cy="24.009293"
cx="24.000891"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.54494413;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient8323);stroke-width:1.00000215;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path7972" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

View file

@ -0,0 +1,293 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="512"
height="512"
viewBox="9 9 30 30"
id="svg7854"
sodipodi:version="0.32"
inkscape:version="0.45"
version="1.0"
sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions"
sodipodi:docname="media-record.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/lapo/Desktop/media-icons.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs7856">
<linearGradient
id="linearGradient7577">
<stop
style="stop-color:#000000;stop-opacity:0.3137255;"
offset="0"
id="stop7579" />
<stop
style="stop-color:#ffffff;stop-opacity:1"
offset="1"
id="stop7581" />
</linearGradient>
<linearGradient
id="linearGradient5167">
<stop
id="stop5169"
offset="0"
style="stop-color:#ef2929;stop-opacity:1;" />
<stop
id="stop5171"
offset="1"
style="stop-color:#c60e0e;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient5184"
inkscape:collect="always">
<stop
id="stop5186"
offset="0"
style="stop-color:white;stop-opacity:1;" />
<stop
id="stop5188"
offset="1"
style="stop-color:white;stop-opacity:0;" />
</linearGradient>
<linearGradient
id="linearGradient5172"
inkscape:collect="always">
<stop
id="stop5174"
offset="0"
style="stop-color:white;stop-opacity:1;" />
<stop
id="stop5176"
offset="1"
style="stop-color:white;stop-opacity:0;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient7577"
id="linearGradient8317"
gradientUnits="userSpaceOnUse"
x1="15.011773"
y1="10.883683"
x2="16.657505"
y2="17.024479" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5167"
id="radialGradient8319"
gradientUnits="userSpaceOnUse"
cx="15.865708"
cy="20.410854"
fx="15.865708"
fy="20.410854"
r="7.5896134" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient5184"
id="radialGradient8321"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-4.2002315,0.5953403,0.2958442,2.0989386,-274.68882,-18.732928)"
cx="14.05685"
cy="11.308558"
fx="14.05685"
fy="11.308558"
r="5.96875" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5172"
id="linearGradient8323"
gradientUnits="userSpaceOnUse"
x1="8.9317284"
y1="2.0178134"
x2="13.458839"
y2="26.431587" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#afafaf"
borderopacity="1"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="-137.53856"
inkscape:cy="10.827794"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="48px"
height="48px"
inkscape:showpageshadow="false"
inkscape:window-width="872"
inkscape:window-height="971"
inkscape:window-x="117"
inkscape:window-y="27"
showgrid="false"
gridspacingx="0.5px"
gridspacingy="0.5px"
gridempspacing="2"
inkscape:grid-points="true"
showborder="true"
showguides="false"
inkscape:guide-bbox="true"
borderlayer="true">
<sodipodi:guide
orientation="horizontal"
position="13.125"
id="guide7377" />
<sodipodi:guide
orientation="horizontal"
position="5.4800776"
id="guide7379" />
<sodipodi:guide
orientation="horizontal"
position="35"
id="guide7492" />
<sodipodi:guide
orientation="horizontal"
position="48"
id="guide7046" />
<sodipodi:guide
orientation="horizontal"
position="-17.5"
id="guide7233" />
<sodipodi:guide
orientation="horizontal"
position="-29"
id="guide7235" />
<sodipodi:guide
orientation="horizontal"
position="22.097087"
id="guide7556" />
<sodipodi:guide
orientation="vertical"
position="-76.125"
id="guide7644" />
<sodipodi:guide
orientation="vertical"
position="-26.125"
id="guide7646" />
<sodipodi:guide
orientation="vertical"
position="24"
id="guide7648" />
<sodipodi:guide
orientation="vertical"
position="-125.28125"
id="guide7665" />
<sodipodi:guide
orientation="vertical"
position="-175.125"
id="guide7667" />
<sodipodi:guide
orientation="vertical"
position="-225.83223"
id="guide7685" />
<sodipodi:guide
orientation="vertical"
position="-326.06462"
id="guide7695" />
</sodipodi:namedview>
<metadata
id="metadata7859">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Lapo Calamandrei</dc:title>
</cc:Agent>
</dc:creator>
<dc:source />
<cc:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:title>Record</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>record</rdf:li>
<rdf:li>media</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:contributor>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g7170"
transform="translate(350,0)">
<path
sodipodi:type="arc"
style="opacity:0.4;color:#000000;fill:url(#linearGradient8317);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.52702755;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path7691"
sodipodi:cx="15.865708"
sodipodi:cy="16.134291"
sodipodi:rx="7.115262"
sodipodi:ry="7.115262"
d="M 22.98097 16.134291 A 7.115262 7.115262 0 1 1 8.7504463,16.134291 A 7.115262 7.115262 0 1 1 22.98097 16.134291 z"
transform="matrix(2.1074616,0,0,2.1078593,-359.43551,-10.006786)" />
<g
id="g7564">
<path
sodipodi:type="arc"
style="color:#000000;fill:url(#radialGradient8319);fill-opacity:1;fill-rule:nonzero;stroke:#a40000;stroke-width:0.52702755;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
id="path7968"
sodipodi:cx="15.865708"
sodipodi:cy="16.134291"
sodipodi:rx="7.115262"
sodipodi:ry="7.115262"
d="M 22.98097 16.134291 A 7.115262 7.115262 0 1 1 8.7504463,16.134291 A 7.115262 7.115262 0 1 1 22.98097 16.134291 z"
transform="matrix(1.897257,0,0,1.897615,-356.10046,-6.6146433)" />
<path
style="opacity:0.64044949;color:#000000;fill:url(#radialGradient8321);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.09465754;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
d="M -324.6139,13.485003 C -329.68021,12.724926 -334.54817,15.857848 -336,20.764516 C -334.81129,23.944906 -332.09189,26.474446 -328.53323,27.241756 C -323.23864,28.383358 -318.03208,25.214213 -316.51818,20.097861 C -317.70687,16.917448 -320.4263,14.387909 -323.98493,13.620622 C -324.20193,13.573837 -324.39741,13.51747 -324.6139,13.485003 z "
id="path7970" />
<path
transform="matrix(1.7591324,0,0,1.7580929,-353.90899,-4.3562887)"
d="M 22.98097 16.134291 A 7.115262 7.115262 0 1 1 8.7504463,16.134291 A 7.115262 7.115262 0 1 1 22.98097 16.134291 z"
sodipodi:ry="7.115262"
sodipodi:rx="7.115262"
sodipodi:cy="16.134291"
sodipodi:cx="15.865708"
id="path7972"
style="opacity:0.54494413;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient8323);stroke-width:0.56863129;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

BIN
icons/status_lagging.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

173
icons/status_lagging.svg Normal file
View file

@ -0,0 +1,173 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.0"
id="svg7854"
height="512"
width="512"
viewBox="9 9 30 30">
<defs
id="defs7856">
<linearGradient
id="linearGradient860">
<stop
id="stop856"
offset="0"
style="stop-color:#ef9d29;stop-opacity:1" />
<stop
id="stop858"
offset="1"
style="stop-color:#c67f0e;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient7577">
<stop
id="stop7579"
offset="0"
style="stop-color:#000000;stop-opacity:0.3137255;" />
<stop
id="stop7581"
offset="1"
style="stop-color:#ffffff;stop-opacity:1" />
</linearGradient>
<linearGradient
id="linearGradient5167">
<stop
style="stop-color:#ef9a29;stop-opacity:1"
offset="0"
id="stop5169" />
<stop
style="stop-color:#a6600c;stop-opacity:1"
offset="1"
id="stop5171" />
</linearGradient>
<linearGradient
id="linearGradient5184">
<stop
style="stop-color:white;stop-opacity:1;"
offset="0"
id="stop5186" />
<stop
style="stop-color:white;stop-opacity:0;"
offset="1"
id="stop5188" />
</linearGradient>
<linearGradient
gradientTransform="matrix(2.1074616,0,0,2.1078593,-9.43551,-10.006786)"
y2="17.024479"
x2="16.657505"
y1="10.883683"
x1="15.011773"
gradientUnits="userSpaceOnUse"
id="linearGradient8317"
xlink:href="#linearGradient7577" />
<radialGradient
gradientTransform="matrix(1.897257,0,0,1.897615,-6.10046,-6.6146433)"
r="7.5896134"
fy="20.410854"
fx="15.865708"
cy="20.410854"
cx="15.865708"
gradientUnits="userSpaceOnUse"
id="radialGradient8319"
xlink:href="#linearGradient5167" />
<radialGradient
r="5.96875"
fy="11.308558"
fx="14.05685"
cy="11.308558"
cx="14.05685"
gradientTransform="matrix(-4.2002315,0.5953403,0.2958442,2.0989386,75.31118,-18.732928)"
gradientUnits="userSpaceOnUse"
id="radialGradient8321"
xlink:href="#linearGradient5184" />
<linearGradient
gradientTransform="matrix(1.7591324,0,0,1.7580929,-3.90899,-4.3562887)"
y2="26.431587"
x2="13.458839"
y1="2.0178134"
x1="8.9317284"
gradientUnits="userSpaceOnUse"
id="linearGradient8323"
xlink:href="#linearGradient860" />
</defs>
<metadata
id="metadata7859">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Lapo Calamandrei</dc:title>
</cc:Agent>
</dc:creator>
<dc:source />
<cc:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:title></dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>record</rdf:li>
<rdf:li>media</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:contributor>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1">
<ellipse
ry="14.997972"
rx="14.995141"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.4;fill:url(#linearGradient8317);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.11079514;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path7691"
cx="24.00086"
cy="24.002029" />
<ellipse
ry="13.502028"
rx="13.49948"
cy="24.002029"
cx="24.000866"
id="path7968"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:url(#radialGradient8319);fill-opacity:1.0;fill-rule:nonzero;stroke:#8e5700;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
<path
id="path7970"
d="M 25.3861,13.485003 C 20.31979,12.724926 15.45183,15.857848 14,20.764516 c 1.18871,3.18039 3.90811,5.70993 7.46677,6.47724 5.29459,1.141602 10.50115,-2.027543 12.01505,-7.143895 -1.18869,-3.180413 -3.90812,-5.709952 -7.46675,-6.477239 -0.217,-0.04678 -0.41248,-0.103152 -0.62897,-0.135619 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.404;fill:url(#radialGradient8321);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.09465754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none" />
<ellipse
ry="12.509292"
rx="12.516688"
cy="24.009293"
cx="24.000891"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:0.54494413;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient8323);stroke-width:1.00000215;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;marker-start:none;marker-mid:none;marker-end:none"
id="path7972" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
icons/status_waiting.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

398
icons/status_waiting.svg Normal file
View file

@ -0,0 +1,398 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://web.resource.org/cc/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
inkscape:export-ydpi="90.000000"
inkscape:export-xdpi="90.000000"
inkscape:export-filename="c:\Tango\git\view-refresh.png"
width="512"
height="512"
viewBox="0 0 48 48"
id="svg11300"
sodipodi:version="0.32"
inkscape:version="0.45"
sodipodi:docbase="/home/dobey/Projects/gnome-icon-theme/scalable/actions"
sodipodi:docname="view-refresh.svg"
version="1.0"
inkscape:r_cx="true"
inkscape:r_cy="true"
inkscape:output_extension="org.inkscape.output.svg.inkscape">
<defs
id="defs3">
<linearGradient
inkscape:collect="always"
id="linearGradient5335">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5337" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5339" />
</linearGradient>
<linearGradient
id="linearGradient5313">
<stop
id="stop5315"
offset="0"
style="stop-color:#99b8df;stop-opacity:1" />
<stop
style="stop-color:#3969a8;stop-opacity:1;"
offset="0.23705086"
id="stop5333" />
<stop
style="stop-color:#4f7eba;stop-opacity:1;"
offset="0.54706067"
id="stop5317" />
<stop
id="stop5321"
offset="0.74557692"
style="stop-color:#96b6d7;stop-opacity:1" />
<stop
style="stop-color:#a0bddc;stop-opacity:1"
offset="0.87321436"
id="stop5331" />
<stop
id="stop5319"
offset="1"
style="stop-color:#729fcf;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient8152">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop8154" />
<stop
id="stop3174"
offset="0.5"
style="stop-color:#4f7eba;stop-opacity:1;" />
<stop
style="stop-color:#729fcf;stop-opacity:1;"
offset="1"
id="stop8156" />
</linearGradient>
<linearGradient
id="linearGradient3207">
<stop
style="stop-color:#eeeeec;stop-opacity:0.47058824;"
offset="0"
id="stop3209" />
<stop
style="stop-color:#eeeeec;stop-opacity:0;"
offset="1"
id="stop3211" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient2847">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop2849" />
<stop
style="stop-color:#3465a4;stop-opacity:0;"
offset="1"
id="stop2851" />
</linearGradient>
<linearGradient
id="linearGradient2831">
<stop
style="stop-color:#3465a4;stop-opacity:1;"
offset="0"
id="stop2833" />
<stop
id="stop2855"
offset="0.33333334"
style="stop-color:#5b86be;stop-opacity:1;" />
<stop
style="stop-color:#83a8d8;stop-opacity:0;"
offset="1"
id="stop2835" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient8662">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop8664" />
<stop
style="stop-color:#000000;stop-opacity:0;"
offset="1"
id="stop8666" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2831"
id="linearGradient1486"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0818662,0,0,1.1166851,-0.8207482,-1.8622434)"
x1="13.478554"
y1="10.612206"
x2="15.419417"
y2="19.115122" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2847"
id="linearGradient1488"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.0818662,0,0,-1.1166851,50.09459,49.644854)"
x1="37.128052"
y1="29.729605"
x2="37.40255"
y2="26.800913" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient8662"
id="radialGradient1503"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1,0,0,0.536723,0,16.87306)"
cx="24.837126"
cy="36.421127"
fx="24.837126"
fy="36.421127"
r="15.644737" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8152"
id="linearGradient8158"
x1="49.412277"
y1="37.904068"
x2="11.881318"
y2="19.776045"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2831"
id="linearGradient8170"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.0818662,0,0,-1.1166851,48.639854,47.862243)"
x1="13.478554"
y1="10.612206"
x2="15.419417"
y2="19.115122" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient2847"
id="linearGradient8172"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0818662,0,0,1.1166851,-2.2754847,-3.644854)"
x1="37.128052"
y1="29.729605"
x2="37.40255"
y2="26.800913" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient8152"
id="linearGradient8174"
gradientUnits="userSpaceOnUse"
x1="49.412277"
y1="37.904068"
x2="11.881318"
y2="19.776045" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3207"
id="linearGradient8178"
gradientUnits="userSpaceOnUse"
x1="5.8925977"
y1="20.540676"
x2="45.198921"
y2="27.721035" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5313"
id="linearGradient8180"
gradientUnits="userSpaceOnUse"
x1="61.572533"
y1="28.049652"
x2="10.969182"
y2="20.333939" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5335"
id="linearGradient5341"
x1="8.6878577"
y1="25.265626"
x2="52.122673"
y2="25.265626"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
stroke="#3465a4"
fill="#729fcf"
id="base"
pagecolor="#ffffff"
bordercolor="#e8e8e8"
borderopacity="0.86666667"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1"
inkscape:cx="48.628749"
inkscape:cy="21.704614"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
inkscape:showpageshadow="false"
inkscape:window-width="892"
inkscape:window-height="938"
inkscape:window-x="374"
inkscape:window-y="37"
width="48px"
height="48px"
borderlayer="true" />
<metadata
id="metadata4">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:creator>
<cc:Agent>
<dc:title>Jakub Steiner</dc:title>
</cc:Agent>
</dc:creator>
<dc:source>http://jimmac.musichall.cz</dc:source>
<cc:license
rdf:resource="http://creativecommons.org/licenses/GPL/2.0/" />
<dc:title>View Refresh</dc:title>
<dc:subject>
<rdf:Bag>
<rdf:li>reload</rdf:li>
<rdf:li>refresh</rdf:li>
<rdf:li>view</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:contributor>
<cc:Agent>
<dc:title>Ricardo 'Rick' González</dc:title>
</cc:Agent>
</dc:contributor>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/GPL/2.0/">
<cc:permits
rdf:resource="http://web.resource.org/cc/Reproduction" />
<cc:permits
rdf:resource="http://web.resource.org/cc/Distribution" />
<cc:requires
rdf:resource="http://web.resource.org/cc/Notice" />
<cc:permits
rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
<cc:requires
rdf:resource="http://web.resource.org/cc/ShareAlike" />
<cc:requires
rdf:resource="http://web.resource.org/cc/SourceCode" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
inkscape:r_cx="true"
inkscape:r_cy="true">
<path
transform="matrix(-1.5146484,0,0,-0.7917058,60.923237,69.528413)"
d="M 40.481863 36.421127 A 15.644737 8.3968935 0 1 1 9.1923885,36.421127 A 15.644737 8.3968935 0 1 1 40.481863 36.421127 z"
sodipodi:ry="8.3968935"
sodipodi:rx="15.644737"
sodipodi:cy="36.421127"
sodipodi:cx="24.837126"
id="path8660"
style="opacity:0.36111109;color:#000000;fill:url(#radialGradient1503);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
sodipodi:type="arc"
inkscape:r_cx="true"
inkscape:r_cy="true" />
<path
style="color:#000000;fill:url(#linearGradient1486);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient1488);stroke-width:1.04300582000000008;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;opacity:0.51807229"
d="M 20.478497,9.7711467 C 20.478497,9.7711467 12.632988,7.9438002 14.368023,21.024298 L 5.1028658,21.024298 C 5.1028658,21.024298 6.0085332,7.5377773 20.478497,9.7711467 z "
id="path2865"
inkscape:r_cx="true"
inkscape:r_cy="true"
sodipodi:nodetypes="cccc" />
<g
id="g1878"
transform="matrix(-0.6129282,-0.5154381,-0.5178496,0.610074,58.686164,13.911361)"
inkscape:r_cx="true"
inkscape:r_cy="true"
style="fill:url(#linearGradient8158);fill-opacity:1;stroke:#204a87;stroke-width:1.24932528;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
<path
sodipodi:nodetypes="ccccccc"
id="path1880"
d="M 45.862102,50.273522 C 62.924432,34.96305 47.150241,15.929711 22.760624,12.513943 L 22.113577,3.1522143 L 7.613534,20.510135 L 22.703188,33.23244 C 22.703188,33.23244 22.454828,23.347105 22.454828,23.347105 C 41.289895,24.339584 54.775794,35.675041 45.862102,50.273522 z "
style="opacity:1;color:#000000;fill:url(#linearGradient8180);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.24977946000000006;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
inkscape:r_cx="true"
inkscape:r_cy="true" />
</g>
<g
style="fill:none;fill-opacity:1;stroke:url(#linearGradient5341);stroke-width:1.24928653000000001;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;opacity:0.54819277"
inkscape:r_cy="true"
inkscape:r_cx="true"
transform="matrix(-0.612811,-0.5154406,-0.5177506,0.6100769,58.675633,13.911365)"
id="g3185">
<path
sodipodi:type="inkscape:offset"
inkscape:radius="-1.197237"
inkscape:original="M 22.125 3.15625 L 7.625 20.5 L 22.71875 33.21875 C 22.718749 33.21875 22.46875 23.34375 22.46875 23.34375 C 41.298509 24.342727 54.468144 35.661007 45.5625 50.25 C 62.614067 34.952315 46.852277 15.923275 22.46875 12.5 L 22.125 3.15625 z "
style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient5341);stroke-width:1.24928653000000001;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible"
id="path3189"
d="M 21.0625,6.3125 L 9.3125,20.34375 L 21.46875,30.59375 C 21.39688,27.754893 21.28125,23.375 21.28125,23.375 C 21.27502,23.044409 21.405774,22.725958 21.642519,22.495132 C 21.879264,22.264306 22.200923,22.141654 22.53125,22.15625 C 32.170255,22.667629 40.441027,25.773015 45.28125,30.875 C 48.676469,34.453835 50.102049,39.131532 49.125,44.21875 C 50.368339,42.205641 51.107893,40.194594 51.375,38.21875 C 51.870422,34.55401 50.856988,30.946652 48.5625,27.59375 C 43.973525,20.887947 34.236978,15.361613 22.3125,13.6875 C 21.732114,13.606381 21.295727,13.117098 21.28125,12.53125 L 21.0625,6.3125 z "
transform="translate(1.0080026e-6,8.5223784e-7)" />
</g>
<g
id="g2424"
transform="matrix(0.190868,0.16126,0.16126,-0.190868,-0.719083,15.30613)"
inkscape:r_cx="true"
inkscape:r_cy="true"
style="opacity:0.5;fill:none;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:r_cy="true"
inkscape:r_cx="true"
id="path8160"
d="M 27.340608,36.228853 C 27.340608,36.228853 35.186117,38.0562 33.451082,24.975702 L 42.71624,24.975702 C 42.71624,24.975702 41.810572,38.462223 27.340608,36.228853 z "
style="color:#000000;fill:url(#linearGradient8170);fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient8172);stroke-width:1.04300582000000008;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;opacity:0.51807229" />
<g
style="fill:url(#linearGradient8174);fill-opacity:1;stroke:#204a87;stroke-width:1.24932528;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:r_cy="true"
inkscape:r_cx="true"
transform="matrix(0.6101332,0.5154999,0.5154881,-0.6101471,-10.618024,32.088556)"
id="g8162">
<path
inkscape:r_cy="true"
inkscape:r_cx="true"
style="opacity:1;color:#000000;fill:url(#linearGradient8180);fill-opacity:1;fill-rule:nonzero;stroke:#204a87;stroke-width:1.25256376;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:block;overflow:visible;enable-background:accumulate"
d="M 45.862102,50.273522 C 62.924432,34.96305 47.150241,15.929711 22.760624,12.513943 L 22.113577,3.1522141 L 7.6135337,20.510135 L 22.703188,33.23244 C 22.703188,33.23244 22.454828,23.347105 22.454828,23.347105 C 41.289895,24.339584 54.775794,35.675041 45.862102,50.273522 z "
id="path8164"
sodipodi:nodetypes="ccccccc" />
</g>
<g
id="g8166"
transform="matrix(0.6128107,0.5154406,0.5177504,-0.6100769,-10.856505,32.088635)"
inkscape:r_cx="true"
inkscape:r_cy="true"
style="fill:none;fill-opacity:1;stroke:#204a87;stroke-width:1.24928653;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
<path
transform="matrix(0.9972307,-2.4605589e-3,-2.4605593e-3,0.9980642,0.2457029,0.2077351)"
d="M 21.0625,6.3125 L 9.3125,20.34375 L 21.46875,30.59375 C 21.39688,27.754893 21.28125,23.375 21.28125,23.375 C 21.27502,23.044409 21.405774,22.725958 21.642519,22.495132 C 21.879264,22.264306 22.200923,22.141654 22.53125,22.15625 C 32.170255,22.667629 40.441027,25.773015 45.28125,30.875 C 48.676469,34.453835 50.102049,39.131532 49.125,44.21875 C 50.368339,42.205641 51.107893,40.194594 51.375,38.21875 C 51.870422,34.55401 50.856988,30.946652 48.5625,27.59375 C 43.973525,20.887947 34.236978,15.361613 22.3125,13.6875 C 21.732114,13.606381 21.295727,13.117098 21.28125,12.53125 L 21.0625,6.3125 z "
id="path8168"
style="opacity:1;color:#000000;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:url(#linearGradient8178);stroke-width:1.24973191;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.70588235;visibility:visible;display:block;overflow:visible"
inkscape:original="M 22.125 3.15625 L 7.625 20.5 L 22.71875 33.21875 C 22.718749 33.21875 22.46875 23.34375 22.46875 23.34375 C 41.298509 24.342727 54.468144 35.661007 45.5625 50.25 C 62.614067 34.952315 46.852277 15.923275 22.46875 12.5 L 22.125 3.15625 z "
inkscape:radius="-1.197237"
sodipodi:type="inkscape:offset" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

BIN
icons/tab_addresses.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

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