Skip to content

Commit

Permalink
feat(SPV-851) add Go examples aligned with js-client (#238)
Browse files Browse the repository at this point in the history
  • Loading branch information
yarex-4chain authored Jun 19, 2024
1 parent b54153a commit 73404c9
Show file tree
Hide file tree
Showing 21 changed files with 596 additions and 111 deletions.
54 changes: 54 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Quick Guide how to run examples

In this directory you can find examples of how to use the `spv-wallet-go-client` package.

## Before you run

### Pre-requisites

- You have access to the `spv-wallet` non-custodial wallet (running locally or remotely).
- You have installed this package on your machine (`go install` on this project's root directory).

### Concerning the keys

- The `ExampleAdminKey` defined in `example_keys.go` is the default one from [spv-wallet-web-backend repository](https://github.com/bitcoin-sv/spv-wallet-web-backend/blob/main/config/viper.go#L56)
- If in your current `spv-wallet` instance you have a different `adminKey`, you should replace the one in `example_keys` with the one you have.
- The `ExampleXPub` and `ExampleXPriv` are just placeholders, which won't work.
- You should replace them by newly generated ones using `task generate_keys`,
- ... or use your actual keys if you have them (don't use the keys which are already added to another wallet).

> Additionally, to make it work properly, you should adjust the `ExamplePaymail` to align with your `domains` configuration in the `spv-wallet` instance.
## Proposed order of executing examples

1. `generate_keys` - generates new keys (you can copy them to `example_keys` if you want to use them in next examples)
2. `admin_add_user` - adds a new user (more precisely adds `ExampleXPub` and then `ExamplePaymail` to the wallet)

> To fully experience the next steps, it would be beneficial to transfer some funds to your `ExamplePaymail`. This ensures the examples run smoothly by demonstrating the creation of a transaction with an actual balance. You can transfer funds to your `ExamplePaymail` using a Bitcoin SV wallet application such as HandCash or any other that supports Paymail.
3. `get_balance` - checks the balance - if you've transferred funds to your `ExamplePaymail`, you should see them here
4. `create_transaction` - creates a transaction (you can adjust the `outputs` to your needs)
5. `list_transactions` - lists all transactions and with example filtering
6. `send_op_return` - sends an OP_RETURN transaction
7. `admin_remove_user` - removes the user

In addition to the above, there are additional examples showing how to use the client from a developer perspective:

- `handle_exceptions` - presents how to "catch" exceptions which the client can throw
- `custom_logger` - shows different ways you can configure (or disable) internal logger

## Util examples

1. `xpriv_from_mnemonic` - allows you to generate/extract an xPriv key from a mnemonic phrase. To you use it you just need to replace the `mnemonic` variable with your own mnemonic phrase.
2. `xpub_from_xpriv` - allows you to generate an xPub key from an xPriv key. To you use it you just need to replace the `xPriv` variable with your own xPriv key.

## How to run an example

The examples are written in Go and can be run by:

```bash
cd examples
task name_of_the_example
```

> See the `examples/Taskfile.yml` for the list of available examples and scripts
63 changes: 63 additions & 0 deletions examples/Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
version: "3"

tasks:
admin_add_user:
desc: "running admin_add_user..."
cmds:
- echo "running admin_add_user..."
- go run ./admin_add_user/admin_add_user.go

admin_remove_user:
desc: "running admin_remove_user..."
cmds:
- echo "running admin_remove_user..."
- go run ./admin_remove_user/admin_remove_user.go

create_transaction:
desc: "running create_transaction..."
cmds:
- echo "running create_transaction..."
- go run ./create_transaction/create_transaction.go

generate_keys:
desc: "running generate_keys..."
cmds:
- echo "running generate_keys..."
- go run ./generate_keys/generate_keys.go

get_balance:
desc: "running get_balance..."
cmds:
- echo "running get_balance..."
- go run ./get_balance/get_balance.go

handle_exceptions:
desc: "running handle_exceptions..."
cmds:
- echo "running handle_exceptions..."
- go run ./handle_exceptions/handle_exceptions.go

list_transactions:
desc: "running list_transactions..."
cmds:
- echo "running list_transactions..."
- go run ./list_transactions/list_transactions.go

send_op_return:
desc: "running send_op_return..."
cmds:
- echo "running send_op_return..."
- go run ./send_op_return/send_op_return.go

xpriv_from_mnemonic:
desc: "running xpriv_from_mnemonic..."
cmds:
- echo "running xpriv_from_mnemonic..."
- go run ./xpriv_from_mnemonic/xpriv_from_mnemonic.go

xpub_from_xpriv:
desc: "running xpub_from_xpriv..."
cmds:
- echo "running xpub_from_xpriv..."
- go run ./xpub_from_xpriv/xpub_from_xpriv.go
36 changes: 36 additions & 0 deletions examples/admin_add_user/admin_add_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Package main - admin_add_user example
*/
package main

import (
"context"
"fmt"
"os"

"examples"
walletclient "github.com/bitcoin-sv/spv-wallet-go-client"
)

func main() {
defer examples.HandlePanic()

examples.CheckIfAdminKeyExists()

server := "http://localhost:3003/v1"

adminClient := walletclient.NewWithAdminKey(server, examples.ExampleAdminKey)
ctx := context.Background()

metadata := map[string]any{"some_metadata": "example"}

newXPubRes := adminClient.AdminNewXpub(ctx, examples.ExampleXPub, metadata)
fmt.Println("AdminNewXpub response: ", newXPubRes)

createPaymailRes, err := adminClient.AdminCreatePaymail(ctx, examples.ExampleXPub, examples.ExamplePaymail, "Some public name", "")
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("AdminCreatePaymail response: ", createPaymailRes)
}
30 changes: 30 additions & 0 deletions examples/admin_remove_user/admin_remove_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Package main - admin_remove_user example
*/
package main

import (
"context"
"fmt"
"os"

"examples"
walletclient "github.com/bitcoin-sv/spv-wallet-go-client"
)

func main() {
defer examples.HandlePanic()

examples.CheckIfAdminKeyExists()

const server = "http://localhost:3003/v1"

adminClient := walletclient.NewWithAdminKey(server, examples.ExampleAdminKey)
ctx := context.Background()

err := adminClient.AdminDeletePaymail(ctx, examples.ExamplePaymail)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
}
43 changes: 43 additions & 0 deletions examples/create_transaction/create_transaction.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Package main - create_transaction example
*/
package main

import (
"context"
"fmt"
"os"

"examples"
walletclient "github.com/bitcoin-sv/spv-wallet-go-client"
)

func main() {
defer examples.HandlePanic()

examples.CheckIfXPrivExists()

const server = "http://localhost:3003/v1"

client := walletclient.NewWithXPriv(server, examples.ExampleXPriv)
ctx := context.Background()

recipient := walletclient.Recipients{To: "[email protected]", Satoshis: 1}
recipients := []*walletclient.Recipients{&recipient}
metadata := map[string]any{"some_metadata": "example"}

newTransaction, err := client.SendToRecipients(ctx, recipients, metadata)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("SendToRecipients response: ", newTransaction)

tx, err := client.GetTransaction(ctx, newTransaction.ID)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("GetTransaction response: ", tx)

}
37 changes: 37 additions & 0 deletions examples/example_keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
Package examples - key constants to be used in the examples and utility function for generating keys
*/
package examples

import (
"fmt"
"os"

"github.com/bitcoin-sv/spv-wallet-go-client/xpriv"
)

const (
// ExampleAdminKey - example admin key
ExampleAdminKey string = "xprv9s21ZrQH143K3CbJXirfrtpLvhT3Vgusdo8coBritQ3rcS7Jy7sxWhatuxG5h2y1Cqj8FKmPp69536gmjYRpfga2MJdsGyBsnB12E19CESK"

// you can generate new keys using `task generate-keys`

// ExampleXPriv - example private key
ExampleXPriv string = ""
// ExampleXPub - example public key
ExampleXPub string = ""

// ExamplePaymail - example Paymail address
ExamplePaymail string = ""
)

// GenerateKeys - function for generating keys (private and public)
func GenerateKeys() xpriv.KeyWithMnemonic {
keys, err := xpriv.Generate()
if err != nil {
fmt.Println(err)
os.Exit(1)
}

return keys
}
19 changes: 19 additions & 0 deletions examples/generate_keys/generate_keys.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
Package main - generate_keys example
*/
package main

import (
"fmt"

"examples"
)

func main() {
keys := examples.GenerateKeys()
exampleXPriv := keys.XPriv()
exampleXPub := keys.XPub().String()

fmt.Println("exampleXPriv: ", exampleXPriv)
fmt.Println("exampleXPub: ", exampleXPub)
}
31 changes: 31 additions & 0 deletions examples/get_balance/get_balance.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Package main - get_balance example
*/
package main

import (
"context"
"fmt"
"os"

"examples"
walletclient "github.com/bitcoin-sv/spv-wallet-go-client"
)

func main() {
defer examples.HandlePanic()

examples.CheckIfXPrivExists()

const server = "http://localhost:3003/v1"

client := walletclient.NewWithXPriv(server, examples.ExampleXPriv)
ctx := context.Background()

xpubInfo, err := client.GetXPub(ctx)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println("Current balance: ", xpubInfo.CurrentBalance)
}
23 changes: 23 additions & 0 deletions examples/go.mod

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions examples/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 73404c9

Please sign in to comment.