Skip to content

Commit

Permalink
Merge pull request #37 from spacemeshos/derivation
Browse files Browse the repository at this point in the history
Key derivation
  • Loading branch information
lrettig authored May 4, 2023
2 parents 68cc94c + 0bbae93 commit 1f92749
Show file tree
Hide file tree
Showing 22 changed files with 826 additions and 577 deletions.
11 changes: 7 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@ jobs:
uses: actions/setup-go@v4
with:
go-version: ${{ env.go-version }}

- name: install musl
uses: awalsh128/cache-apt-pkgs-action@v1
with:
packages: musl-tools # provides musl-gcc
version: 1.0
- name: build
run: go build -v ./...

run: make build
- name: go test
run: go test -v ./...
run: make test
63 changes: 47 additions & 16 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,59 @@
name: Build and Release

env:
go-version: "1.19"

on:
release:
types: [created]

jobs:
releases-matrix:
name: Release Go Binary
runs-on: ubuntu-latest
release:
strategy:
matrix:
# build and publish in parallel: linux/amd64, linux/arm64, windows/amd64, darwin/amd64, darwin/arm64
goos: [linux, windows, darwin]
goarch: [amd64, arm64]
exclude:
- goarch: arm64
goos: windows
include:
- image: macos-latest
name: macos-amd64
- image: ubuntu-latest
name: linux-amd64
- image: windows-latest
name: windows-amd64
binaryextension: .exe
- image: [self-hosted, macos, arm64]
name: macos-arm64
- image: [self-hosted, linux, arm64]
name: linux-arm64
env:
BINARY_NAME: smcli${{ matrix.binaryextension }}
ARTIFACT_NAME: smcli-${{ github.event.release.tag_name }}-${{ matrix.name }}.tar.gz
runs-on: ${{ matrix.image }}
name: Release ${{ matrix.name }}
steps:
- uses: actions/checkout@v3
- uses: wangyoucao577/go-release-action@v1
- name: Checkout
uses: actions/checkout@v3
- name: Set up go
uses: actions/setup-go@v4
with:
go-version: ${{ env.go-version }}
- name: Install musl
if: contains(matrix.name, 'linux')
uses: awalsh128/cache-apt-pkgs-action@v1
with:
packages: musl-tools # provides musl-gcc
version: 1.0
- name: Build
run: make build
- name: Prepare files
shell: bash
# if: ${{ !contains(matrix.name, 'windows') }}
run: |
mkdir artifacts
mv LICENSE README.md ${{ env.BINARY_NAME }} artifacts
cd artifacts
tar -czf ${{ env.ARTIFACT_NAME }} *
mv ${{ env.ARTIFACT_NAME }} ..
- name: Release
uses: softprops/action-gh-release@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
goarch: ${{ matrix.goarch }}
binary_name: sm
asset_name: "smcli-${{ github.event.release.tag_name }}-${{ matrix.goos }}-${{ matrix.goarch }}"
extra_files: LICENSE README.md
files: ${{ env.ARTIFACT_NAME }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

# Dependency directories (remove the comment below to include it)
# vendor/
deps/

# Go workspace file
go.work
Expand Down
121 changes: 121 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Based on https://gist.github.com/trosendal/d4646812a43920bfe94e

DEPTAG := 1.0.7
DEPLIBNAME := ed25519_bip32
DEPLOC := https://github.com/spacemeshos/$(DEPLIBNAME)/releases/download
DEPLIB := lib$(DEPLIBNAME)
# Exclude dylib files (we only need the static libs)
EXCLUDE_PATTERN := "LICENSE" "*.so" "*.dylib"
UNZIP_DEST := deps
REAL_DEST := $(shell realpath .)/$(UNZIP_DEST)
DOWNLOAD_DEST := $(UNZIP_DEST)/$(DEPLIB).tar.gz
EXTLDFLAGS := -L$(UNZIP_DEST) -l$(DEPLIBNAME)

# Detect operating system
ifeq ($(OS),Windows_NT)
SYSTEM := windows
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
SYSTEM := linux
else ifeq ($(UNAME_S),Darwin)
SYSTEM := darwin
else
$(error Unknown operating system: $(UNAME_S))
endif
endif

# Default values. Can be overridden on command line, e.g., inside CLI for cross-compilation.
# Note: this Makefile structure theoretically supports cross-compilation using GOOS and GOARCH.
# In practice, however, depending on the host and target OS/architecture, you'll likely run into
# errors in both the compiler and the linker when trying to compile cross-platform.
GOOS ?= $(SYSTEM)
GOARCH ?= unknown

# Detect processor architecture
ifeq ($(GOARCH),unknown)
UNAME_M := $(shell uname -m)
ifeq ($(UNAME_M),x86_64)
GOARCH := amd64
else ifneq ($(filter %86,$(UNAME_M)),)
$(error Unsupported processor architecture: $(UNAME_M))
else ifneq ($(filter arm%,$(UNAME_M)),)
GOARCH := arm64
else ifneq ($(filter aarch64%,$(UNAME_M)),)
GOARCH := arm64
else
$(error Unknown processor architecture: $(UNAME_M))
endif
endif

ifeq ($(GOOS),linux)
MACHINE = linux

# Linux specific settings
# We do a static build on Linux using musl toolchain
CPREFIX = CC=musl-gcc
LDFLAGS = -linkmode external -extldflags "-static $(EXTLDFLAGS)"
else ifeq ($(GOOS),darwin)
MACHINE = macos

# macOS specific settings
# dynamic build using default toolchain
LDFLAGS = -extldflags "$(EXTLDFLAGS)"
else ifeq ($(GOOS),windows)
# static build using default toolchain
# add a few extra required libs
LDFLAGS = -linkmode external -extldflags "-static $(EXTLDFLAGS) -lws2_32 -luserenv -lbcrypt"
else
$(error Unknown operating system: $(GOOS))
endif

ifeq ($(SYSTEM),windows)
# Windows settings
# TODO: this is probably unnecessary, most Windows dev environments (including GHA)
# should support bash
RM = del /Q /F
RMDIR = rmdir /S /Q
MKDIR = mkdir

FN = $(DEPLIB)_windows-amd64.zip
DOWNLOAD_DEST = $(UNZIP_DEST)/$(DEPLIB).zip
EXTRACT = 7z x -y

# TODO: fix this, it doesn't seem to work as expected
#EXCLUDES = -x!$(EXCLUDE_PATTERN)
else
# Linux and macOS settings
RM = rm -f
RMDIR = rm -rf
MKDIR = mkdir -p
EXCLUDES = $(addprefix --exclude=,$(EXCLUDE_PATTERN))
EXTRACT = tar -xzf

ifeq ($(GOARCH),amd64)
PLATFORM = $(MACHINE)-amd64
else ifeq ($(GOARCH),arm64)
PLATFORM = $(MACHINE)-arm64
else
$(error Unknown processor architecture: $(GOARCH))
endif
FN = $(DEPLIB)_$(PLATFORM).tar.gz
endif

$(UNZIP_DEST): $(DOWNLOAD_DEST)
cd $(UNZIP_DEST) && $(EXTRACT) ../$(DOWNLOAD_DEST) $(EXCLUDES)

$(DOWNLOAD_DEST):
$(MKDIR) $(UNZIP_DEST)
curl -sSfL $(DEPLOC)/v$(DEPTAG)/$(FN) -o $(DOWNLOAD_DEST)

.PHONY: build
build: $(UNZIP_DEST)
$(CPREFIX) GOOS=$(GOOS) GOARCH=$(GOARCH) CGO_ENABLED=1 go build -ldflags '$(LDFLAGS)'

.PHONY: test
test: $(UNZIP_DEST)
LD_LIBRARY_PATH=$(REAL_DEST) go test -v -ldflags "-extldflags \"-L$(REAL_DEST) -led25519_bip32\"" ./...

clean:
$(RM) $(DOWNLOAD_DEST)
$(RMDIR) $(UNZIP_DEST)
18 changes: 14 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
# smcli: Spacemesh Command-line Interface Tool

smcli is a simple tool that you can use to manage wallet files and a running Spacemesh node. It currently supports the following features:
smcli is a simple command line tool that you can use to manage wallet files (in the future it may be expanded with additional functionality).

It currently supports the following features. Note that this documentation is not intended to be as complete as the built-in help documentation in the application itself, which fully documents all commands, flags, and features. Run `smcli -h` to see this documentation.

## Wallet

smcli allows you to read encrypted wallet files (including those created using Smapp and other compatible tools), and generate new wallet files.

### Reading

To read an encrypted wallet file, run `sm wallet read <filename>`. You'll be prompted to enter the password used to encrypt the wallet file. If you enter the correct password, you'll see the contents of the wallet printed, including the accounts it contains.
To read an encrypted wallet file, run `smcli wallet read <filename>`. You'll be prompted to enter the (optional) password used to encrypt the wallet file. If you enter the correct password, you'll see the contents of the wallet printed, including the accounts it contains. Include the flags `--full` to see full keys, and `--private` to see private keys and mnemonic in addition to public keys.

Note that you can read both wallet files created using `smcli` as well as those created using [Smapp](https://github.com/spacemeshos/smapp/) or any other tool that supports standard Spacemesh wallet format.

### Generation

To generate a new wallet containing a random keypair, run `sm wallet create`.
To generate a new wallet, run `smcli wallet create`. The command will prompt you to enter a [BIP39-compatible mnemonic](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki), or alternatively generate a new, random mnemonic for you. It will then prompt you to enter a password to encrypt the wallet file (optional but highly recommended) and will then generate an encrypted wallet file with one or more new keypairs.

Note that these keypairs (public and private key) are _not_ the same as Spacemesh wallet addresses. The public key can be converted directly and deterministically into your wallet address; in other words, there is a one-to-one mapping between public keys and wallet addresses. Conversion and outputting of public keys as wallet addresses [will be available shortly](https://github.com/spacemeshos/smcli/issues/38).

#### Hardware wallet support

Support for hardware wallets such as Ledger devices is not currently available in `smcli` but will be [added shortly](https://github.com/spacemeshos/smcli/issues/10).

**NOTE: We strongly recommend only creating a new wallet on a secure, airgapped computer. You are responsible for safely storing your wallet files. There is absolutely nothing that we can do to help you recover your wallet if you misplace the file.**
**NOTE: We strongly recommend only creating a new wallet on a secure, airgapped computer. You are responsible for safely storing your mnemonic and wallet files. Your mnemonic is the ONLY way to restore access to your wallet and accounts if you misplace the wallet file, so it's essential that you back it up securely and reliably. There is absolutely nothing that we can do to help you recover your wallet if you misplace the file or mnemonic.**
Loading

0 comments on commit 1f92749

Please sign in to comment.