diff --git a/.github/workflows/ark.release.yaml b/.github/workflows/ark.release.yaml index b7f0430..4a504d2 100755 --- a/.github/workflows/ark.release.yaml +++ b/.github/workflows/ark.release.yaml @@ -1,52 +1,122 @@ -name: release +name: Release ark on: - workflow_dispatch: - push: - tags: - - "*" - paths: - - "server/**" - + release: + types: [released] jobs: - goreleaser: - runs-on: ubuntu-20.04 - defaults: - run: - working-directory: ./server - env: - DOCKER_CLI_EXPERIMENTAL: "enabled" + build: + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-go@v3 - with: - go-version: ">1.17.2" - - uses: actions/cache@v1 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - uses: docker/login-action@v1 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: release artifacts - uses: goreleaser/goreleaser-action@v2 - with: - version: latest - args: release --rm-dist --debug - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} - - uses: bufbuild/buf-setup-action@v1.3.1 - - name: release protos - uses: bufbuild/buf-push-action@v1 - with: - input: api-spec/protobuf - buf_token: ${{ secrets.BUF_TOKEN }} - \ No newline at end of file + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Go + uses: actions/setup-go@v2 + with: + go-version: 1.21.0 + + - name: Build binaries + run: make build-all + + - name: Upload server binary (Linux, AMD64) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./server/build/arkd-linux-amd64 + asset_name: arkd-linux-amd64 + asset_content_type: application/octet-stream + + - name: Upload server binary (Linux, ARM) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./server/build/arkd-linux-arm64 + asset_name: arkd-linux-arm + asset_content_type: application/octet-stream + + - name: Upload server binary (Darwin, AMD64) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./server/build/arkd-darwin-amd64 + asset_name: arkd-darwin-amd64 + asset_content_type: application/octet-stream + + - name: Upload server binary (Darwin, ARM) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./server/build/arkd-darwin-arm64 + asset_name: arkd-darwin-arm + asset_content_type: application/octet-stream + + # CLI + - name: Upload client binary (Linux, AMD64) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./client/build/ark-linux-amd64 + asset_name: ark-linux-amd64 + asset_content_type: application/octet-stream + + - name: Upload client binary (Linux, ARM) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./client/build/ark-linux-arm64 + asset_name: ark-linux-arm + asset_content_type: application/octet-stream + + - name: Upload client binary (Darwin, AMD64) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./client/build/ark-darwin-amd64 + asset_name: ark-darwin-amd64 + asset_content_type: application/octet-stream + + - name: Upload client binary (Darwin, ARM) + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_path: ./client/build/ark-darwin-arm64 + asset_name: ark-darwin-arm + asset_content_type: application/octet-stream + + + # Docker + + - name: Set up Docker + uses: docker/setup-buildx-action@v1 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Docker image + uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: ghcr.io/${{ github.repository }}:${{ github.event.release.tag_name }} + platforms: linux/amd64,linux/arm64 \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b22e353 --- /dev/null +++ b/Makefile @@ -0,0 +1,20 @@ +.PHONY: build-server build-client build-all-server build-all-client + +build-server: + @echo "Building arkd binary..." + @bash ./server/scripts/build + +build-client: + @echo "Building ark binary..." + @bash ./client/scripts/build + +build-all-server: + @echo "Building arkd binary for all archs..." + @bash ./server/scripts/build-all + +build-all-client: + @echo "Building ark binary for all archs..." + @bash ./client/scripts/build-all + +build: build-server build-client +build-all: build-all-server build-all-client \ No newline at end of file diff --git a/README.md b/README.md index 1a73371..3ee9a5c 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,160 @@ Welcome to the Ark monorepo. In this repository you can find: -- `server` - a proof of concept of an Ark Service Provider. -- `client` - the initial Ark wallet, served as CLI. +- `server` - always-on daemon that serves as the Ark Service Provider (ASP) +- `client` - single-key wallet as command-line interface (CLI) to interact with the ASP +## Get Started with Docker + +Run locally with Docker on Liquid Testnet. It uses `docker-compose` to build the `arkd` docker image from `server` and run the it as container, together with the `oceand` container. + +### Prerequisites + +- [Go](https://go.dev/doc/install) +- [Docker](https://docs.docker.com/engine/install/) + +### Setup the Ocean wallet + +Start `oceand` in Liquid Testnet: + +```bash +docker compose up -d oceand +``` + +Setup `oceand`: + +```bash +alias ocean='docker exec oceand ocean' +ocean config init --no-tls +ocean wallet create --password +ocean wallet unlock --password +``` + +### Run arkd connected to Ocean + +Build from source `./server` and start the ASP: + +```bash +docker compose up -d arkd +``` + +**Note:** On startup `arkd` will create an account `ark` on oceand. + +Get an address from Ocean to add funds to the ASP: + +```bash +ocean account derive --account-name ark +``` + +Fund the resulting address with [Liquid testnet faucet](https://liquidtestnet.com/faucet). + +### Ark client + +Inside the `arkd` container is shipped the `ark` CLI. You can submit payment to the ASP using the `ark` CLI. + +```bash +alias ark='docker exec arkd ark' +ark init --password --ark-url localhost:6000 +``` + +This will add a `state.json` file to the following directory: + +- POSIX (Linux/BSD): ~/.Ark-cli +- Mac OS: $HOME/Library/Application Support/Ark-cli +- Windows: %LOCALAPPDATA%\Ark-cli +- Plan 9: $home/Ark-cli + +**Note:** you can use a different datadir by exporting the env var `ARK_WALLET_DATADIR` like: + +```bash +export ARK_WALLET_DATADIR=path/to/custom +ark init --password --ark-url localhost:6000 +``` + +Add funds to the ark wallet: + +```bash +ark receive +{ + "offchain_address":
, + "onchain_address":
+} +``` + +Fund the `onchain_address` with https://liquidtestnet.com/faucet. + +Onboard the ark: + +```bash +ark onboard --amount 21000 +``` + +After confirmation, ark wallet will be funded and ready to spend offchain. + +In **another tab**, setup another ark wallet with: + +```bash +export ARK_WALLET_DATADIR=./datadir +alias ark2=$(pwd)/build/ark-- +ark2 init --password --ark-url localhost:6000 +``` + +**Note:** `ark2` should always run in the second tab. + +### Make payments + +You can now make ark payments between the 2 ark wallets: + +```bash +ark2 receive +{ + "offchain_address":
, + "onchain_address":
, + "relays": ["localhost:6000"] +} +``` + +```bash +ark send --to --amount 2100 +``` + +Both balances should reflect the payment: + +```bash +ark balance +{ + "offchain_balance": 18900, + "onchain_balance": 0 +} +``` + +```bash + ark2 balance +{ + "offchain_balance": 2100, + "onchain_balance": 0 +} +``` + +### Exiting + +User `ark` can leave the ark collaboratively (i.e. ASP needs to collaborate): + +```bash +ark redeem --address --amount 12100 +``` + +In the case of the ASP is not responding, you can leave the ark unilaterally (`--amount` is not necessary since `--force` will redeem all funds): + +```bash +ark redeem --address --force +``` + +### Help + +You can see all available commands with `help`: + +```bash +ark help +``` diff --git a/client/init.go b/client/init.go index ce1aa2a..7fe841d 100644 --- a/client/init.go +++ b/client/init.go @@ -24,7 +24,7 @@ var ( networkFlag = cli.StringFlag{ Name: "network", Usage: "network to use (liquid, testnet, regtest)", - Value: "testnet", + Value: "liquid", } urlFlag = cli.StringFlag{ Name: "ark-url", diff --git a/client/main.go b/client/main.go index 2591482..5bfa321 100644 --- a/client/main.go +++ b/client/main.go @@ -16,7 +16,7 @@ import ( const ( DATADIR_ENVVAR = "ARK_WALLET_DATADIR" STATE_FILE = "state.json" - defaultNetwork = "testnet" + defaultNetwork = "liquid" ASP_URL = "asp_url" ASP_PUBKEY = "asp_public_key" diff --git a/docker-compose.yml b/docker-compose.yml index 447c796..bad08c9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,6 +29,7 @@ services: environment: - ARK_WALLET_ADDR=oceand:18000 - ARK_ROUND_INTERVAL=10 + - ARK_NETWORK=testnet ports: - "6000:6000" volumes: diff --git a/server/README.md b/server/README.md index 7bb2cf2..491205f 100755 --- a/server/README.md +++ b/server/README.md @@ -1,165 +1,27 @@ -### Overview +# Ark Server -This is a Go implementation of Ark Service Provider that uses covenants (on the Liquid network). +This is a Go implementation of an Ark Service Provider (ASP). An ASP it's an always-on server that provide Bitcoin liquidity to the Ark protocol. It's built using the [Elements introspection opcodes](https://github.com/ElementsProject/elements/blob/master/doc/tapscript_opcodes.md) and currenlty supports Elements as chain of deployment. -This is a Proof of Concept in a early phase of development. +This is in a early phase of development, the goal is to experiment with many possibile use-cases of Ark and adapt quickly based on user feedback early on. -### Requirements +**ALPHA STAGE SOFTWARE: USE AT YOUR OWN RISK!** + +## Development + +### Prerequisites - [Go](https://go.dev/doc/install) -- [Ocean](https://github.com/vulpemventures/ocean) -- [Docker](https://docs.docker.com/engine/install/) -### Ocean wallet - -Start oceand: - -``` -$ docker compose up -d oceand -``` - -Setup oceand: - -``` -$ alias ocean='docker exec oceand ocean' -$ ocean config init --no-tls -$ ocean wallet create --password -$ ocean wallet unlock --password -``` - -### Ark Service Provider - -Start the ASP: - -``` -$ docker compose up -d arkd -``` - -**Note:** On startup `arkd` will create an account `ark` on oceand. - -Add funds to the ASP: - -``` -$ ocean account derive --account-name ark -``` - -Fund the resulting address with https://liquidtestnet.com/faucet. - -### Ark client - -Build ark client: - -``` -$ cd client -$ make build -$ alias ark=$(pwd)/build/ark-- -``` - -Initialise ark wallet: - -``` -$ ark init --password --ark-url localhost:6000 -``` - -This will add a `state.json` file to the following directory: - -- POSIX (Linux/BSD): ~/.Ark-cli -- Mac OS: $HOME/Library/Application Support/Ark-cli -- Windows: %LOCALAPPDATA%\Ark-cli -- Plan 9: $home/Ark-cli - -**Note:** you can use a different datadir by exporting the env var `ARK_WALLET_DATADIR` like: +### Build Server ```bash -$ export ARK_WALLET_DATADIR=path/to/custom -$ ark init --password --ark-url localhost:6000 +make build ``` -Add funds to the ark wallet: +### Run the server -``` -$ ark receive -{ - "offchain_address":
, - "onchain_address":
-} +```bash +go run ./cmd/arkd ``` -Fund the `onchain_address` with https://liquidtestnet.com/faucet. - -Onboard the ark: - -``` -$ ark onboard --amount 21000 -``` - -After confirmation, ark wallet will be funded and ready to spend offchain. - -In **another tab**, setup another ark wallet with: - -``` -$ export ARK_WALLET_DATADIR=./datadir -$ alias ark2=$(pwd)/build/ark-- -$ ark2 init --password --ark-url localhost:6000 -``` - -**Note:** `ark2` should always run in the second tab. - -### Make payments - -You can now make ark payments between the 2 ark wallets: - -``` -$ ark2 receive -{ - "offchain_address":
, - "onchain_address":
, - "relays": [ - "localhost:6000" - ] -} -``` - -``` -$ ark send --to --amount 2100 -``` - -Both balances should reflect the payment: - -``` -$ ark balance -{ - "offchain_balance": 18900, - "onchain_balance": 78872 -} -``` - -``` -$ ark2 balance -{ - "offchain_balance": 2100, - "onchain_balance": 0 -} -``` - -### Exiting - -User `ark` can leave the ark collaboratively (i.e. ASP needs to collaborate): - -``` -$ ark redeem --address --amount 12100 -``` - -In the case of the ASP is not responding, you can leave the ark unilaterally (`--amount` is not necessary since `--force` will redeem all funds): - -``` -$ ark redeem --address --force -``` - -### Help - -You can see all available commands with `help`: - -``` -$ ark help -``` +Refer to [config.go](./internal/config/config.go) for the available configuration options via ENV VARs. \ No newline at end of file diff --git a/server/internal/config/config.go b/server/internal/config/config.go index 017759d..3b3c8c4 100644 --- a/server/internal/config/config.go +++ b/server/internal/config/config.go @@ -44,18 +44,19 @@ var ( UnilateralExitDelay = "UNILATERAL_EXIT_DELAY" defaultDatadir = common.AppDataDir("arkd", false) - defaultRoundInterval = 10 + defaultRoundInterval = 5 defaultPort = 6000 + defaultWalletAddr = "localhost:18000" defaultDbType = "badger" defaultSchedulerType = "gocron" defaultTxBuilderType = "covenant" defaultBlockchainScannerType = "ocean" defaultInsecure = true - defaultNetwork = "testnet" - defaultLogLevel = 5 - defaultMinRelayFee = 30 - defaultRoundLifetime = 512 - defaultUnilateralExitDelay = 512 + defaultNetwork = "liquid" + defaultLogLevel = 4 + defaultMinRelayFee = 30 // 0.1 sat/vbyte on Liquid + defaultRoundLifetime = 604800 // 1 week + defaultUnilateralExitDelay = 1440 // 1 day ) func LoadConfig() (*Config, error) { @@ -63,18 +64,19 @@ func LoadConfig() (*Config, error) { viper.AutomaticEnv() viper.SetDefault(Datadir, defaultDatadir) - viper.SetDefault(RoundInterval, defaultRoundInterval) viper.SetDefault(Port, defaultPort) viper.SetDefault(DbType, defaultDbType) - viper.SetDefault(SchedulerType, defaultSchedulerType) - viper.SetDefault(TxBuilderType, defaultTxBuilderType) - viper.SetDefault(BlockchainScannerType, defaultBlockchainScannerType) viper.SetDefault(Insecure, defaultInsecure) viper.SetDefault(LogLevel, defaultLogLevel) viper.SetDefault(Network, defaultNetwork) - viper.SetDefault(RoundLifetime, defaultRoundLifetime) + viper.SetDefault(WalletAddr, defaultWalletAddr) viper.SetDefault(MinRelayFee, defaultMinRelayFee) + viper.SetDefault(RoundInterval, defaultRoundInterval) + viper.SetDefault(RoundLifetime, defaultRoundLifetime) + viper.SetDefault(SchedulerType, defaultSchedulerType) + viper.SetDefault(TxBuilderType, defaultTxBuilderType) viper.SetDefault(UnilateralExitDelay, defaultUnilateralExitDelay) + viper.SetDefault(BlockchainScannerType, defaultBlockchainScannerType) net, err := getNetwork() if err != nil {