diff --git a/.travis.yml b/.travis.yml index 4e34d02..25d54fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,4 @@ language: go go: - - master \ No newline at end of file + - master +script: go test -v ./btc/ \ No newline at end of file diff --git a/btc/path_address_test.go b/btc/path_address_test.go index 0a6d18e..c4d5842 100644 --- a/btc/path_address_test.go +++ b/btc/path_address_test.go @@ -10,32 +10,81 @@ import ( func TestAddress(t *testing.T) { b, storage := getTestBackend(t) - exp := MissingTokenError - _, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "address/wallet1", - Operation: logical.UpdateOperation, - }) - if err == nil { - t.Fatal("Should have failed before") - } - if err.Error() != exp { - t.Fatalf("Want: %v, got: %v", exp, err) + name := "test" + network := "testnet" + _, err := newWallet(t, b, storage, name, network) + if err != nil { + t.Fatal(err) } - exp = InvalidTokenError - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "address/wallet1", + resp, err := newAuthToken(t, b, storage, name) + token := resp.Data["token"].(string) + + t.Run("Get address for wallet", func(t *testing.T) { + resp, err := newAddress(t, b, storage, name, token) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Get address with expired auth token should fail", func(t *testing.T) { + t.Parallel() + + exp := InvalidTokenError + _, err := newAddress(t, b, storage, name, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got %v", exp, err) + } + }) + + t.Run("Get address without auth token should fail", func(t *testing.T) { + t.Parallel() + + token := "" + exp := MissingTokenError + _, err := newAddress(t, b, storage, name, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) + + t.Run("Get address with invalid auth token should fail", func(t *testing.T) { + t.Parallel() + + token := "testtoken" + exp := InvalidTokenError + _, err := newAddress(t, b, storage, name, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newAddress(t *testing.T, b logical.Backend, store logical.Storage, name string, token string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Storage: store, + Path: "address/" + name, Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "token": "testtoken", - }, + Data: map[string]interface{}{"token": token}, }) - if err == nil { - t.Fatal("Should have failed before") + if err != nil { + return nil, err } - if err.Error() != exp { - t.Fatalf("Want: %v, got: %v", exp, err) + if resp.IsError() { + return nil, resp.Error() } + + return resp, nil } diff --git a/btc/path_credentials_test.go b/btc/path_credentials_test.go index c66ab49..3c18fe2 100644 --- a/btc/path_credentials_test.go +++ b/btc/path_credentials_test.go @@ -10,16 +10,52 @@ import ( func TestCredentials(t *testing.T) { b, storage := getTestBackend(t) - exp := "Failed to create credentials for 'wallet1': wallet does not exist" - _, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "creds/wallet1", + name := "test" + network := "testnet" + _, err := newWallet(t, b, storage, name, network) + if err != nil { + t.Fatal(err) + } + + t.Run("Create auth token for wallet", func(t *testing.T) { + t.Parallel() + + resp, err := newAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Create auth token for bad wallet should fail", func(t *testing.T) { + t.Parallel() + + name := "badwallet" + exp := "Failed to create credentials for '" + name + "': wallet does not exist" + _, err := newAuthToken(t, b, storage, name) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newAuthToken(t *testing.T, b logical.Backend, store logical.Storage, name string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Path: "creds/" + name, + Storage: store, Operation: logical.ReadOperation, }) - if err == nil { - t.Fatal("Should have failed before") + if err != nil { + return nil, err } - if err.Error() != exp { - t.Fatalf("Want: %v, got: %v", exp, err) + if resp.IsError() { + return nil, resp.Error() } + + return resp, nil } diff --git a/btc/path_multisig_address_test.go b/btc/path_multisig_address_test.go index ebce665..834937f 100644 --- a/btc/path_multisig_address_test.go +++ b/btc/path_multisig_address_test.go @@ -10,32 +10,84 @@ import ( func TestMultiSigAddress(t *testing.T) { b, storage := getTestBackend(t) - exp := MissingTokenError - _, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "address/multisig/wallet1", - Operation: logical.UpdateOperation, - }) - if err == nil { - t.Fatal("Should have failed before") - } - if err.Error() != exp { - t.Fatalf("Want: %v, got: %v", exp, err) + m := 2 + n := 3 + name := "test" + network := "testnet" + pubkeys := []string{"", ""} + _, err := newMultiSigWallet(t, b, storage, name, network, m, n, pubkeys) + if err != nil { + t.Fatal(err) } - exp = InvalidTokenError - _, err = b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "address/multisig/wallet1", + resp, err := newMultiSigAuthToken(t, b, storage, name) + token := resp.Data["token"].(string) + + t.Run("Get address for multisig wallet", func(t *testing.T) { + resp, err := newMultiSigAddress(t, b, storage, name, token) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Get address with expired auth token should fail", func(t *testing.T) { + t.Parallel() + + exp := InvalidTokenError + _, err := newMultiSigAddress(t, b, storage, name, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got %v", exp, err) + } + }) + + t.Run("Get address without auth token should fail", func(t *testing.T) { + t.Parallel() + + token := "" + exp := MissingTokenError + _, err := newMultiSigAddress(t, b, storage, name, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) + + t.Run("Get address with invalid auth token should fail", func(t *testing.T) { + t.Parallel() + + token := "testtoken" + exp := InvalidTokenError + _, err := newMultiSigAddress(t, b, storage, name, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newMultiSigAddress(t *testing.T, b logical.Backend, store logical.Storage, name string, token string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Storage: store, + Path: "address/multisig/" + name, Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "token": "testtoken", - }, + Data: map[string]interface{}{"token": token}, }) - if err == nil { - t.Fatal("Should have failed before") + if err != nil { + return nil, err } - if err.Error() != exp { - t.Fatalf("Want: %v, got: %v", exp, err) + if resp.IsError() { + return nil, resp.Error() } + + return resp, nil } diff --git a/btc/path_multisig_credentials_test.go b/btc/path_multisig_credentials_test.go index 845ce65..4ac2e7a 100644 --- a/btc/path_multisig_credentials_test.go +++ b/btc/path_multisig_credentials_test.go @@ -10,16 +10,55 @@ import ( func TestMultiSigCredentials(t *testing.T) { b, storage := getTestBackend(t) - exp := "Failed to create credentials for 'multisig_wallet1': wallet does not exist" - _, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "creds/multisig/wallet1", + m := 2 + n := 3 + name := "test" + network := "testnet" + pubkeys := []string{"", ""} + _, err := newMultiSigWallet(t, b, storage, name, network, m, n, pubkeys) + if err != nil { + t.Fatal(err) + } + + t.Run("Create auth token for multisig wallet", func(t *testing.T) { + t.Parallel() + + resp, err := newMultiSigAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Create auth token for bad multisig wallet should fail", func(t *testing.T) { + t.Parallel() + + name := "badwallet" + exp := "Failed to create credentials for '" + MultiSigPrefix + name + "': wallet does not exist" + _, err := newMultiSigAuthToken(t, b, storage, name) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newMultiSigAuthToken(t *testing.T, b logical.Backend, store logical.Storage, name string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Path: "creds/multisig/" + name, + Storage: store, Operation: logical.ReadOperation, }) - if err == nil { - t.Fatal("Should have failed before") + if err != nil { + return nil, err } - if err.Error() != exp { - t.Fatalf("Want: %v, got: %v", exp, err) + if resp.IsError() { + return nil, resp.Error() } + + return resp, nil } diff --git a/btc/path_multisig_wallet_test.go b/btc/path_multisig_wallet_test.go new file mode 100644 index 0000000..fbbea95 --- /dev/null +++ b/btc/path_multisig_wallet_test.go @@ -0,0 +1,140 @@ +package btc + +import ( + "context" + "errors" + "testing" + + "github.com/hashicorp/vault/logical" +) + +func TestMultiSigWallet(t *testing.T) { + b, storage := getTestBackend(t) + m := 2 + n := 3 + name := "test" + network := "testnet" + pubkeys := []string{ + "04b353e7164238cc9106db773e0fa26507ede05ff78b31100ac47f9e328587bf2e7e740377ccbc29c5584bf13e2a05e47bfb8aa2529d4b2e91fe6879269da36c66", + "04179f874d9fc892f6b9d2cbc3aefea47f39f364d7a8e0c8bc3d6f1af1659160cb319f713260379bf26c0811505a471e9620fbb7404b4e8a0089a6d9cde301be3b", + } + + t.Run("Create multisig wallet", func(t *testing.T) { + // not checking response cause this returns nil if successful + _, err := newMultiSigWallet(t, b, storage, name, network, m, n, pubkeys) + if err != nil { + t.Fatal(err) + } + }) + + t.Run("Get multisig wallet info", func(t *testing.T) { + t.Parallel() + + resp, err := getMultiSigWallet(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + t.Log(resp.Data) + }) + + t.Run("Create multisig wallet with missing params should fail", func(t *testing.T) { + t.Parallel() + + err := badRequest(t, b, storage, name, "", m, n, pubkeys) + if err != nil { + t.Fatal(err) + } + + err = badRequest(t, b, storage, name, network, 0, n, pubkeys) + if err != nil { + t.Fatal(err) + } + + err = badRequest(t, b, storage, name, network, m, 0, pubkeys) + if err != nil { + t.Fatal(err) + } + + err = badRequest(t, b, storage, name, network, m, n, []string{}) + if err != nil { + t.Fatal(err) + } + }) + + t.Run("Create an existing multisig wallet should fail", func(t *testing.T) { + t.Parallel() + + exp := "MultiSig wallet with name '" + MultiSigPrefix + name + "' already exists" + _, err := newMultiSigWallet(t, b, storage, name, network, m, n, pubkeys) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newMultiSigWallet(t *testing.T, b logical.Backend, store logical.Storage, name string, network string, m int, n int, pubkeys []string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Storage: store, + Path: "wallet/multisig/" + name, + Operation: logical.UpdateOperation, + Data: map[string]interface{}{ + "m": m, + "n": n, + "pubkeys": pubkeys, + "network": network, + }, + }) + if err != nil { + return nil, err + } + if resp.IsError() { + return nil, resp.Error() + } + + return resp, nil +} + +func getMultiSigWallet(t *testing.T, b logical.Backend, store logical.Storage, name string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Storage: store, + Path: "wallet/multisig/" + name, + Operation: logical.ReadOperation, + }) + if err != nil { + return nil, err + } + if resp.IsError() { + return nil, resp.Error() + } + + return resp, nil +} + +func badRequest(t *testing.T, b logical.Backend, store logical.Storage, name string, network string, m int, n int, pubkeys []string) error { + exp := MissingNetworkError + if m == 0 { + exp = InvalidMError + } + if n == 0 { + exp = InvalidNError + } + if len(pubkeys) == 0 { + exp = MissingPubKeysError + } + + _, err := newMultiSigWallet(t, b, store, name, network, m, n, pubkeys) + if err == nil { + return errors.New("Should have failed before") + } + if err.Error() != exp { + return errors.New("Want: " + exp + ", got: " + err.Error()) + } + + return nil +} diff --git a/btc/path_transaction_test.go b/btc/path_transaction_test.go new file mode 100644 index 0000000..6d244c5 --- /dev/null +++ b/btc/path_transaction_test.go @@ -0,0 +1,100 @@ +package btc + +import ( + "context" + "testing" + + "github.com/hashicorp/vault/logical" +) + +func TestTransaction(t *testing.T) { + b, storage := getTestBackend(t) + + name := "test" + network := "testnet" + _, err := newWallet(t, b, storage, name, network) + if err != nil { + t.Fatal(err) + } + + resp, err := newAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token := resp.Data["token"].(string) + isMultisig := false + rawTx := "0100000001be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396000000001976a914dd6cce9f255a8cc17bda8ba0373df8e861cb866e88acffffffff0123ce0100000000001976a9142bc89c2702e0e618db7d59eb5ce2f0f147b4075488ac0000000001000000" + + t.Run("Sign transaction for BIP44 wallet", func(t *testing.T) { + + resp, err := newSignature(t, b, storage, name, rawTx, isMultisig, token) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Sign transaction with expired token should fail", func(t *testing.T) { + t.Parallel() + + exp := InvalidTokenError + _, err := newSignature(t, b, storage, name, rawTx, isMultisig, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) + + t.Run("Sign transaction without token should fail", func(t *testing.T) { + t.Parallel() + + token := "" + exp := MissingTokenError + _, err := newSignature(t, b, storage, name, rawTx, isMultisig, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) + + t.Run("Sign transaction with invalid token should fail", func(t *testing.T) { + t.Parallel() + + token := "testtoken" + exp := InvalidTokenError + _, err := newSignature(t, b, storage, name, rawTx, isMultisig, token) + if err == nil { + t.Fatal("Should have failed before") + } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newSignature(t *testing.T, b logical.Backend, store logical.Storage, name string, rawTx string, multisig bool, token string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Path: "transaction/" + name, + Storage: store, + Operation: logical.UpdateOperation, + Data: map[string]interface{}{ + "multisig": multisig, + "rawTx": rawTx, + "token": token, + }, + }) + if err != nil { + return nil, err + } + if resp.IsError() { + return nil, resp.Error() + } + + return resp, nil +} diff --git a/btc/path_wallet_test.go b/btc/path_wallet_test.go index 6136b8c..990dd9c 100644 --- a/btc/path_wallet_test.go +++ b/btc/path_wallet_test.go @@ -9,16 +9,37 @@ import ( func TestWallet(t *testing.T) { b, storage := getTestBackend(t) + name := "test" + network := "testnet" - t.Run("Create wallet", func(t *testing.T) { + t.Run("Create BIP44 wallet", func(t *testing.T) { + resp, err := newWallet(t, b, storage, name, network) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Get BIP44 wallet info", func(t *testing.T) { + t.Parallel() + resp, err := getWallet(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + if resp == nil { + t.Fatal("No response received") + } + }) + + t.Run("Create BIP44 wallet without network should fail", func(t *testing.T) { t.Parallel() + name := "testwallet" + network := "" exp := MissingNetworkError - _, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "wallet/testwallet", - Operation: logical.UpdateOperation, - }) + _, err := newWallet(t, b, storage, name, network) if err == nil { t.Fatal("Should have failed before") } @@ -27,17 +48,50 @@ func TestWallet(t *testing.T) { } }) - t.Run("Get extendend public key", func(t *testing.T) { + t.Run("Create an existing BIP44 wallet should fail", func(t *testing.T) { t.Parallel() - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "wallet/wallet", - Operation: logical.ReadOperation, - }) - - if err == nil && resp != nil { + exp := "Wallet with name '" + name + "' already exists" + _, err := newWallet(t, b, storage, name, network) + if err == nil { t.Fatal("Should have failed before") } + if err.Error() != exp { + t.Fatalf("Want: %v, got: %v", exp, err) + } + }) +} + +func newWallet(t *testing.T, b logical.Backend, store logical.Storage, name string, network string) (*logical.Response, error) { + data := map[string]interface{}{"network": network} + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Storage: store, + Path: "wallet/" + name, + Operation: logical.UpdateOperation, + Data: data, }) + if err != nil { + return nil, err + } + if resp.IsError() { + return nil, resp.Error() + } + + return resp, nil +} + +func getWallet(t *testing.T, b logical.Backend, store logical.Storage, name string) (*logical.Response, error) { + resp, err := b.HandleRequest(context.Background(), &logical.Request{ + Storage: store, + Path: "wallet/" + name, + Operation: logical.ReadOperation, + }) + if err != nil { + return nil, err + } + if resp.IsError() { + return nil, resp.Error() + } + + return resp, nil } diff --git a/btc/plugin_multisig_test.go b/btc/plugin_multisig_test.go index b4aa4e9..015ded7 100644 --- a/btc/plugin_multisig_test.go +++ b/btc/plugin_multisig_test.go @@ -1,73 +1,80 @@ package btc import ( - "context" "testing" - - "github.com/hashicorp/vault/logical" ) func TestMultiSigPlugin(t *testing.T) { b, storage := getTestBackend(t) - pubkeys := "04b353e7164238cc9106db773e0fa26507ede05ff78b31100ac47f9e328587bf2e7e740377ccbc29c5584bf13e2a05e47bfb8aa2529d4b2e91fe6879269da36c66,04179f874d9fc892f6b9d2cbc3aefea47f39f364d7a8e0c8bc3d6f1af1659160cb319f713260379bf26c0811505a471e9620fbb7404b4e8a0089a6d9cde301be3b" + name := "test" + network := "testnet" + m := 2 + n := 3 + pubkeys := []string{ + "04b353e7164238cc9106db773e0fa26507ede05ff78b31100ac47f9e328587bf2e7e740377ccbc29c5584bf13e2a05e47bfb8aa2529d4b2e91fe6879269da36c66", + "04179f874d9fc892f6b9d2cbc3aefea47f39f364d7a8e0c8bc3d6f1af1659160cb319f713260379bf26c0811505a471e9620fbb7404b4e8a0089a6d9cde301be3b", + } + rawTx := "0100000001be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396000000001976a914dd6cce9f255a8cc17bda8ba0373df8e861cb866e88acffffffff0123ce0100000000001976a9142bc89c2702e0e618db7d59eb5ce2f0f147b4075488ac0000000001000000" + + t.Logf("Test Parameters\nWallet name: %s\nWallet network: %s\nM: %d\nN: %d\nPublic keys: %s\nRaw transaction: %s\n", name, network, m, n, pubkeys, rawTx) + // create new multisig wallet + _, err := newMultiSigWallet(t, b, storage, name, network, m, n, pubkeys) + if err != nil { + t.Fatal(err) + } + + // retrieve wallet info + resp, err := getMultiSigWallet(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + t.Logf("%v", resp.Data) - t.Run("Generate receiving address", func(t *testing.T) { - var token string + // create auth token for multisig address + resp, err = newMultiSigAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token := resp.Data["token"].(string) - t.Run("Create auth token for wallet", func(t *testing.T) { - t.Run("Path wallet/multisig/", func(t *testing.T) { - t.Run("Create multisig wallet", func(t *testing.T) { - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "wallet/multisig/testwallet", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "network": "testnet", - "m": 2, - "n": 3, - "pubkeys": pubkeys, - }, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } - }) + // derive address + resp, err = newMultiSigAddress(t, b, storage, name, token) + if err != nil { + t.Fatal(err) + } + firstAddress := resp.Data["address"].(string) - t.Run("Get multisig wallet info", func(t *testing.T) { - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "wallet/multisig/testwallet", - Operation: logical.ReadOperation, - }) + // create auth token for multisig address + resp, err = newMultiSigAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token = resp.Data["token"].(string) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } - }) - }) + // derive address + resp, err = newMultiSigAddress(t, b, storage, name, token) + if err != nil { + t.Fatal(err) + } + secondAddress := resp.Data["address"].(string) - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "creds/multisig/testwallet", - Operation: logical.ReadOperation, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } + // check that they don't match + if firstAddress != secondAddress { + t.Fatalf("Different requests generated the different addresses: %s, %s", firstAddress, secondAddress) + } + t.Logf("Multisig wallet address: %s", firstAddress) - token = resp.Data["token"].(string) - }) + // create auth token for signature + resp, err = newMultiSigAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token = resp.Data["token"].(string) - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "address/multisig/testwallet", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "token": token, - }, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } - }) + // create signature for raw transaction + resp, err = newSignature(t, b, storage, name, rawTx, true, token) + if err != nil { + t.Fatal(err) + } + t.Logf("Partial signature for raw tx: %s", resp.Data["signature"].(string)) } diff --git a/btc/plugin_test.go b/btc/plugin_test.go index a5b5100..32d1004 100644 --- a/btc/plugin_test.go +++ b/btc/plugin_test.go @@ -1,69 +1,75 @@ package btc import ( - "context" "testing" - - "github.com/hashicorp/vault/logical" ) func TestPlugin(t *testing.T) { b, storage := getTestBackend(t) + name := "test" + network := "testnet" + rawTx := "0100000001be66e10da854e7aea9338c1f91cd489768d1d6d7189f586d7a3613f2a24d5396000000001976a914dd6cce9f255a8cc17bda8ba0373df8e861cb866e88acffffffff0123ce0100000000001976a9142bc89c2702e0e618db7d59eb5ce2f0f147b4075488ac0000000001000000" + + t.Logf("Test Parameters\nWallet name: %s\nWallet network: %s\nRaw transaction: %s\n", name, network, rawTx) + // create new BIP44 wallet + resp, err := newWallet(t, b, storage, name, network) + if err != nil { + t.Fatal(err) + } + t.Logf("Mnemonic: %s", resp.Data["mnemonic"].(string)) + + // retrieve wallet info + resp, err = getWallet(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + t.Logf("Tpub: %s", resp.Data["xpub"].(string)) - t.Run("Generate receiving address", func(t *testing.T) { - var token string + // create auth token for first address + resp, err = newAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token := resp.Data["token"].(string) - t.Run("Create auth token for wallet", func(t *testing.T) { - t.Run("Path wallet/", func(t *testing.T) { - t.Run("Create wallet", func(t *testing.T) { - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "wallet/testwallet", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "network": "testnet", - }, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } - }) + // derive first address + resp, err = newAddress(t, b, storage, name, token) + if err != nil { + t.Fatal(err) + } + firstAddress := resp.Data["address"].(string) - t.Run("Get extended public key", func(t *testing.T) { - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "wallet/testwallet", - Operation: logical.ReadOperation, - }) + // create auth token for second address + resp, err = newAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token = resp.Data["token"].(string) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } - }) - }) + // derive second address + resp, err = newAddress(t, b, storage, name, token) + if err != nil { + t.Fatal(err) + } + secondAddress := resp.Data["address"].(string) - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "creds/testwallet", - Operation: logical.ReadOperation, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } + // check that they don't match + if firstAddress == secondAddress { + t.Fatal("Different requests generated the same address: " + firstAddress) + } + t.Logf("Derived addresses: %s, %s", firstAddress, secondAddress) - token = resp.Data["token"].(string) - }) + // create auth token for signature + resp, err = newAuthToken(t, b, storage, name) + if err != nil { + t.Fatal(err) + } + token = resp.Data["token"].(string) - resp, err := b.HandleRequest(context.Background(), &logical.Request{ - Storage: storage, - Path: "address/testwallet", - Operation: logical.UpdateOperation, - Data: map[string]interface{}{ - "token": token, - }, - }) - if err != nil || (resp != nil && resp.IsError()) { - t.Fatalf("bad: resp: %#v\nerr: %v\n", resp, err) - } - }) + // create signature for raw transaction + resp, err = newSignature(t, b, storage, name, rawTx, false, token) + if err != nil { + t.Fatal(err) + } + t.Logf("Signature for raw tx: %s", resp.Data["signature"].(string)) }