mirror of
https://github.com/AthanorLabs/atomic-swap.git
synced 2026-01-09 14:18:03 -05:00
add private key proof to SendKeyMessage, verify on receipt (#62)
This commit is contained in:
@@ -2,6 +2,7 @@ package monero
|
||||
|
||||
import (
|
||||
"github.com/noot/atomic-swap/common"
|
||||
"github.com/noot/atomic-swap/monero/crypto"
|
||||
"github.com/noot/atomic-swap/rpcclient"
|
||||
)
|
||||
|
||||
@@ -10,9 +11,9 @@ type Client interface {
|
||||
GetAccounts() (*getAccountsResponse, error)
|
||||
GetAddress(idx uint) (*getAddressResponse, error)
|
||||
GetBalance(idx uint) (*GetBalanceResponse, error)
|
||||
Transfer(to Address, accountIdx, amount uint) (*TransferResponse, error)
|
||||
GenerateFromKeys(kp *PrivateKeyPair, filename, password string, env common.Environment) error
|
||||
GenerateViewOnlyWalletFromKeys(vk *PrivateViewKey, address Address, filename, password string) error
|
||||
Transfer(to crypto.Address, accountIdx, amount uint) (*TransferResponse, error)
|
||||
GenerateFromKeys(kp *crypto.PrivateKeyPair, filename, password string, env common.Environment) error
|
||||
GenerateViewOnlyWalletFromKeys(vk *crypto.PrivateViewKey, address crypto.Address, filename, password string) error
|
||||
GetHeight() (uint, error)
|
||||
Refresh() error
|
||||
OpenWallet(filename, password string) error
|
||||
@@ -38,7 +39,7 @@ func (c *client) GetBalance(idx uint) (*GetBalanceResponse, error) {
|
||||
return c.callGetBalance(idx)
|
||||
}
|
||||
|
||||
func (c *client) Transfer(to Address, accountIdx, amount uint) (*TransferResponse, error) {
|
||||
func (c *client) Transfer(to crypto.Address, accountIdx, amount uint) (*TransferResponse, error) {
|
||||
destination := Destination{
|
||||
Amount: amount,
|
||||
Address: string(to),
|
||||
@@ -47,11 +48,12 @@ func (c *client) Transfer(to Address, accountIdx, amount uint) (*TransferRespons
|
||||
return c.callTransfer([]Destination{destination}, accountIdx)
|
||||
}
|
||||
|
||||
func (c *client) GenerateFromKeys(kp *PrivateKeyPair, filename, password string, env common.Environment) error {
|
||||
return c.callGenerateFromKeys(kp.sk, kp.vk, kp.Address(env), filename, password)
|
||||
func (c *client) GenerateFromKeys(kp *crypto.PrivateKeyPair, filename, password string, env common.Environment) error {
|
||||
return c.callGenerateFromKeys(kp.SpendKey(), kp.ViewKey(), kp.Address(env), filename, password)
|
||||
}
|
||||
|
||||
func (c *client) GenerateViewOnlyWalletFromKeys(vk *PrivateViewKey, address Address, filename, password string) error {
|
||||
func (c *client) GenerateViewOnlyWalletFromKeys(vk *crypto.PrivateViewKey, address crypto.Address,
|
||||
filename, password string) error {
|
||||
return c.callGenerateFromKeys(nil, vk, address, filename, password)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/noot/atomic-swap/common"
|
||||
"github.com/noot/atomic-swap/monero/crypto"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -38,15 +39,15 @@ func TestClient_Transfer(t *testing.T) {
|
||||
t.Fatal("need to wait for balance to unlock")
|
||||
}
|
||||
|
||||
kpA, err := GenerateKeys()
|
||||
kpA, err := crypto.GenerateKeys()
|
||||
require.NoError(t, err)
|
||||
|
||||
kpB, err := GenerateKeys()
|
||||
kpB, err := crypto.GenerateKeys()
|
||||
require.NoError(t, err)
|
||||
|
||||
kpABPub := SumSpendAndViewKeys(kpA.PublicKeyPair(), kpB.PublicKeyPair())
|
||||
kpABPub := crypto.SumSpendAndViewKeys(kpA.PublicKeyPair(), kpB.PublicKeyPair())
|
||||
|
||||
vkABPriv := SumPrivateViewKeys(kpA.vk, kpB.vk)
|
||||
vkABPriv := crypto.SumPrivateViewKeys(kpA.ViewKey(), kpB.ViewKey())
|
||||
|
||||
r, err := rand.Int(rand.Reader, big.NewInt(10000))
|
||||
require.NoError(t, err)
|
||||
@@ -82,7 +83,7 @@ func TestClient_Transfer(t *testing.T) {
|
||||
_ = daemon.callGenerateBlocks(aliceAddress.Address, 16)
|
||||
|
||||
// generate spend account for A+B
|
||||
skAKPriv := SumPrivateSpendKeys(kpA.sk, kpB.sk)
|
||||
skAKPriv := crypto.SumPrivateSpendKeys(kpA.SpendKey(), kpB.SpendKey())
|
||||
// ignore the error for now, as it can error with "Wallet already exists."
|
||||
_ = cB.callGenerateFromKeys(skAKPriv, vkABPriv, kpABPub.Address(common.Mainnet),
|
||||
fmt.Sprintf("test-wallet-%d", r), "")
|
||||
@@ -97,6 +98,6 @@ func TestClient_Transfer(t *testing.T) {
|
||||
}
|
||||
|
||||
// transfer from account A+B back to Alice's address
|
||||
_, err = cB.Transfer(Address(aliceAddress.Address), 0, 1)
|
||||
_, err = cB.Transfer(crypto.Address(aliceAddress.Address), 0, 1)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
58
monero/crypto/address.go
Normal file
58
monero/crypto/address.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"github.com/noot/atomic-swap/common"
|
||||
)
|
||||
|
||||
const (
|
||||
addressPrefixMainnet byte = 18
|
||||
addressPrefixStagenet byte = 24
|
||||
)
|
||||
|
||||
// Address represents a base58-encoded string
|
||||
type Address string
|
||||
|
||||
func getChecksum(data ...[]byte) (result [4]byte) {
|
||||
keccak256 := Keccak256(data...)
|
||||
copy(result[:], keccak256[:4])
|
||||
return
|
||||
}
|
||||
|
||||
// AddressBytes returns the address as bytes for a PrivateKeyPair with the given environment (ie. mainnet or stagenet)
|
||||
func (kp *PrivateKeyPair) AddressBytes(env common.Environment) []byte {
|
||||
return kp.PublicKeyPair().AddressBytes(env)
|
||||
}
|
||||
|
||||
// Address returns the base58-encoded address for a PrivateKeyPair with the given environment
|
||||
// (ie. mainnet or stagenet)
|
||||
func (kp *PrivateKeyPair) Address(env common.Environment) Address {
|
||||
return Address(EncodeMoneroBase58(kp.AddressBytes(env)))
|
||||
}
|
||||
|
||||
// AddressBytes returns the address as bytes for a PublicKeyPair with the given environment (ie. mainnet or stagenet)
|
||||
func (kp *PublicKeyPair) AddressBytes(env common.Environment) []byte {
|
||||
psk := kp.sk.key.Bytes()
|
||||
pvk := kp.vk.key.Bytes()
|
||||
c := append(psk, pvk...)
|
||||
|
||||
var prefix byte
|
||||
switch env {
|
||||
case common.Mainnet, common.Development:
|
||||
prefix = addressPrefixMainnet
|
||||
case common.Stagenet:
|
||||
prefix = addressPrefixStagenet
|
||||
}
|
||||
|
||||
// address encoding is:
|
||||
// (network_prefix) + (32-byte public spend key) + (32-byte-byte public view key)
|
||||
// + first_4_Bytes(Hash(network_prefix + (32-byte public spend key) + (32-byte public view key)))
|
||||
checksum := getChecksum(append([]byte{prefix}, c...))
|
||||
addr := append(append([]byte{prefix}, c...), checksum[:4]...)
|
||||
return addr
|
||||
}
|
||||
|
||||
// Address returns the base58-encoded address for a PublicKeyPair with the given environment
|
||||
// (ie. mainnet or stagenet)
|
||||
func (kp *PublicKeyPair) Address(env common.Environment) Address {
|
||||
return Address(EncodeMoneroBase58(kp.AddressBytes(env)))
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// this file is from https://github.com/paxosglobal/moneroutil/tree/33d7e0c11a62d2ac67213781a0b485d0de4aca70
|
||||
|
||||
package monero
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
@@ -1,7 +1,8 @@
|
||||
package monero
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/sha512"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
@@ -11,69 +12,9 @@ import (
|
||||
"github.com/noot/atomic-swap/common"
|
||||
|
||||
ed25519 "filippo.io/edwards25519"
|
||||
"github.com/ebfe/keccak"
|
||||
"github.com/ethereum/go-ethereum/crypto/secp256k1"
|
||||
)
|
||||
|
||||
const (
|
||||
addressPrefixMainnet byte = 18
|
||||
addressPrefixStagenet byte = 24
|
||||
)
|
||||
|
||||
// PublicSpendOnSecp256k1 returns a public spend key on the secp256k1 curve
|
||||
func PublicSpendOnSecp256k1(k []byte) (x, y *big.Int) {
|
||||
return secp256k1.S256().ScalarBaseMult(k)
|
||||
}
|
||||
|
||||
// SumSpendAndViewKeys sums two PublicKeyPairs, returning another PublicKeyPair.
|
||||
func SumSpendAndViewKeys(a, b *PublicKeyPair) *PublicKeyPair {
|
||||
return &PublicKeyPair{
|
||||
sk: SumPublicKeys(a.sk, b.sk),
|
||||
vk: SumPublicKeys(a.vk, b.vk),
|
||||
}
|
||||
}
|
||||
|
||||
// SumPublicKeys sums two public keys (points)
|
||||
func SumPublicKeys(a, b *PublicKey) *PublicKey {
|
||||
s := ed25519.NewIdentityPoint().Add(a.key, b.key)
|
||||
return &PublicKey{
|
||||
key: s,
|
||||
}
|
||||
}
|
||||
|
||||
// SumPrivateSpendKeys sums two private spend keys (scalars)
|
||||
func SumPrivateSpendKeys(a, b *PrivateSpendKey) *PrivateSpendKey {
|
||||
s := ed25519.NewScalar().Add(a.key, b.key)
|
||||
return &PrivateSpendKey{
|
||||
key: s,
|
||||
}
|
||||
}
|
||||
|
||||
// SumPrivateViewKeys sums two private view keys (scalars)
|
||||
func SumPrivateViewKeys(a, b *PrivateViewKey) *PrivateViewKey {
|
||||
s := ed25519.NewScalar().Add(a.key, b.key)
|
||||
return &PrivateViewKey{
|
||||
key: s,
|
||||
}
|
||||
}
|
||||
|
||||
// Keccak256 returns the keccak256 hash of the data.
|
||||
func Keccak256(data ...[]byte) (result [32]byte) {
|
||||
h := keccak.New256()
|
||||
for _, b := range data {
|
||||
h.Write(b)
|
||||
}
|
||||
r := h.Sum(nil)
|
||||
copy(result[:], r)
|
||||
return
|
||||
}
|
||||
|
||||
func getChecksum(data ...[]byte) (result [4]byte) {
|
||||
keccak256 := Keccak256(data...)
|
||||
copy(result[:], keccak256[:4])
|
||||
return
|
||||
}
|
||||
|
||||
const privateKeySize = 32
|
||||
|
||||
var (
|
||||
@@ -118,39 +59,11 @@ func NewPrivateKeyPairFromBytes(skBytes, vkBytes []byte) (*PrivateKeyPair, error
|
||||
}, nil
|
||||
}
|
||||
|
||||
// AddressBytes returns the address as bytes for a PrivateKeyPair with the given environment (ie. mainnet or stagenet)
|
||||
func (kp *PrivateKeyPair) AddressBytes(env common.Environment) []byte {
|
||||
psk := kp.sk.Public().key.Bytes()
|
||||
pvk := kp.vk.Public().key.Bytes()
|
||||
c := append(psk, pvk...)
|
||||
|
||||
var prefix byte
|
||||
switch env {
|
||||
case common.Mainnet, common.Development:
|
||||
prefix = addressPrefixMainnet
|
||||
case common.Stagenet:
|
||||
prefix = addressPrefixStagenet
|
||||
}
|
||||
|
||||
// address encoding is:
|
||||
// 0x12+(32-byte public spend key) + (32-byte-byte public view key)
|
||||
// + First_4_Bytes(Hash(0x12+(32-byte public spend key) + (32-byte public view key)))
|
||||
checksum := getChecksum(append([]byte{prefix}, c...))
|
||||
addr := append(append([]byte{prefix}, c...), checksum[:4]...)
|
||||
return addr
|
||||
}
|
||||
|
||||
// SpendKeyBytes returns the canoncail byte encoding of the private spend key.
|
||||
func (kp *PrivateKeyPair) SpendKeyBytes() []byte {
|
||||
return kp.sk.key.Bytes()
|
||||
}
|
||||
|
||||
// Address returns the base58-encoded address for a PrivateKeyPair with the given environment
|
||||
// (ie. mainnet or stagenet)
|
||||
func (kp *PrivateKeyPair) Address(env common.Environment) Address {
|
||||
return Address(EncodeMoneroBase58(kp.AddressBytes(env)))
|
||||
}
|
||||
|
||||
// PublicKeyPair returns the PublicKeyPair corresponding to the PrivateKeyPair
|
||||
func (kp *PrivateKeyPair) PublicKeyPair() *PublicKeyPair {
|
||||
return &PublicKeyPair{
|
||||
@@ -182,7 +95,8 @@ func (kp *PrivateKeyPair) Marshal(env common.Environment) ([]byte, error) {
|
||||
|
||||
// PrivateSpendKey represents a monero private spend key
|
||||
type PrivateSpendKey struct {
|
||||
key *ed25519.Scalar
|
||||
seed [32]byte
|
||||
key *ed25519.Scalar
|
||||
}
|
||||
|
||||
// NewPrivateSpendKey returns a new PrivateSpendKey from the given canonically-encoded scalar.
|
||||
@@ -388,50 +302,63 @@ func (kp *PublicKeyPair) ViewKey() *PublicKey {
|
||||
return kp.vk
|
||||
}
|
||||
|
||||
// AddressBytes returns the address as bytes for a PublicKeyPair with the given environment (ie. mainnet or stagenet)
|
||||
func (kp *PublicKeyPair) AddressBytes(env common.Environment) []byte {
|
||||
psk := kp.sk.key.Bytes()
|
||||
pvk := kp.vk.key.Bytes()
|
||||
c := append(psk, pvk...)
|
||||
|
||||
var prefix byte
|
||||
switch env {
|
||||
case common.Mainnet, common.Development:
|
||||
prefix = addressPrefixMainnet
|
||||
case common.Stagenet:
|
||||
prefix = addressPrefixStagenet
|
||||
}
|
||||
|
||||
// address encoding is:
|
||||
// 0x12+(32-byte public spend key) + (32-byte-byte public view key)
|
||||
// + First_4_Bytes(Hash(0x12+(32-byte public spend key) + (32-byte public view key)))
|
||||
checksum := getChecksum(append([]byte{prefix}, c...))
|
||||
addr := append(append([]byte{prefix}, c...), checksum[:4]...)
|
||||
return addr
|
||||
}
|
||||
|
||||
// Address returns the base58-encoded address for a PublicKeyPair with the given environment
|
||||
// (ie. mainnet or stagenet)
|
||||
func (kp *PublicKeyPair) Address(env common.Environment) Address {
|
||||
return Address(EncodeMoneroBase58(kp.AddressBytes(env)))
|
||||
}
|
||||
|
||||
// GenerateKeys returns a private spend key and view key
|
||||
// GenerateKeys generates a private spend key and view key
|
||||
func GenerateKeys() (*PrivateKeyPair, error) {
|
||||
var seed [64]byte
|
||||
var seed [32]byte
|
||||
_, err := rand.Read(seed[:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := ed25519.NewScalar().SetUniformBytes(seed[:])
|
||||
// we hash the seed for compatibility w/ the ed25519 stdlib
|
||||
h := sha512.Sum512(seed[:])
|
||||
|
||||
s, err := ed25519.NewScalar().SetBytesWithClamping(h[:32])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to set bytes: %w", err)
|
||||
}
|
||||
|
||||
sk := &PrivateSpendKey{
|
||||
key: s,
|
||||
seed: seed,
|
||||
key: s,
|
||||
}
|
||||
|
||||
return sk.AsPrivateKeyPair()
|
||||
}
|
||||
|
||||
// PublicSpendOnSecp256k1 returns a public spend key on the secp256k1 curve
|
||||
func PublicSpendOnSecp256k1(k []byte) (x, y *big.Int) {
|
||||
return secp256k1.S256().ScalarBaseMult(k)
|
||||
}
|
||||
|
||||
// SumSpendAndViewKeys sums two PublicKeyPairs, returning another PublicKeyPair.
|
||||
func SumSpendAndViewKeys(a, b *PublicKeyPair) *PublicKeyPair {
|
||||
return &PublicKeyPair{
|
||||
sk: SumPublicKeys(a.sk, b.sk),
|
||||
vk: SumPublicKeys(a.vk, b.vk),
|
||||
}
|
||||
}
|
||||
|
||||
// SumPublicKeys sums two public keys (points)
|
||||
func SumPublicKeys(a, b *PublicKey) *PublicKey {
|
||||
s := ed25519.NewIdentityPoint().Add(a.key, b.key)
|
||||
return &PublicKey{
|
||||
key: s,
|
||||
}
|
||||
}
|
||||
|
||||
// SumPrivateSpendKeys sums two private spend keys (scalars)
|
||||
func SumPrivateSpendKeys(a, b *PrivateSpendKey) *PrivateSpendKey {
|
||||
s := ed25519.NewScalar().Add(a.key, b.key)
|
||||
return &PrivateSpendKey{
|
||||
key: s,
|
||||
}
|
||||
}
|
||||
|
||||
// SumPrivateViewKeys sums two private view keys (scalars)
|
||||
func SumPrivateViewKeys(a, b *PrivateViewKey) *PrivateViewKey {
|
||||
s := ed25519.NewScalar().Add(a.key, b.key)
|
||||
return &PrivateViewKey{
|
||||
key: s,
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package monero
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
14
monero/crypto/hash.go
Normal file
14
monero/crypto/hash.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package crypto
|
||||
|
||||
import "github.com/ebfe/keccak"
|
||||
|
||||
// Keccak256 returns the keccak256 hash of the data.
|
||||
func Keccak256(data ...[]byte) (result [32]byte) {
|
||||
h := keccak.New256()
|
||||
for _, b := range data {
|
||||
h.Write(b)
|
||||
}
|
||||
r := h.Sum(nil)
|
||||
copy(result[:], r)
|
||||
return
|
||||
}
|
||||
54
monero/crypto/sign.go
Normal file
54
monero/crypto/sign.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
)
|
||||
|
||||
// Signature represents an ed25519 signature
|
||||
type Signature struct {
|
||||
s []byte
|
||||
}
|
||||
|
||||
// NewSignatureFromHex returns a new Signature from the given hex-encoded string.
|
||||
// The string must be 64 bytes.
|
||||
func NewSignatureFromHex(s string) (*Signature, error) {
|
||||
b, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(b) != ed25519.SignatureSize {
|
||||
return nil, errors.New("invalid length for signature")
|
||||
}
|
||||
|
||||
return &Signature{
|
||||
s: b,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Hex returns the signature as a hex-encoded string.
|
||||
func (s *Signature) Hex() string {
|
||||
return hex.EncodeToString(s.s)
|
||||
}
|
||||
|
||||
// Sign signs the given message with the private key.
|
||||
// The private key must have been created with GenerateKeys().
|
||||
func (k *PrivateSpendKey) Sign(msg []byte) (*Signature, error) {
|
||||
if k.seed == [32]byte{} {
|
||||
return nil, errors.New("private key does not have seed, key must be created with GenerateKeys")
|
||||
}
|
||||
|
||||
pub := k.Public().key.Bytes()
|
||||
pk := ed25519.PrivateKey(append(k.seed[:], pub...))
|
||||
return &Signature{
|
||||
s: ed25519.Sign(pk, msg),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Verify verifies that the message was signed with the given signature and key.
|
||||
func (k *PublicKey) Verify(msg []byte, sig *Signature) bool {
|
||||
pk := ed25519.PublicKey(k.key.Bytes())
|
||||
return ed25519.Verify(pk, msg, sig.s)
|
||||
}
|
||||
44
monero/crypto/sign_test.go
Normal file
44
monero/crypto/sign_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPrivateSpendKey_Sign(t *testing.T) {
|
||||
kp, err := GenerateKeys()
|
||||
require.NoError(t, err)
|
||||
|
||||
msg := []byte("testmessage")
|
||||
sig, err := kp.sk.Sign(msg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, sig)
|
||||
}
|
||||
|
||||
func TestPrivateSpendKey_Verify(t *testing.T) {
|
||||
kp, err := GenerateKeys()
|
||||
require.NoError(t, err)
|
||||
|
||||
msg := []byte("testmessage")
|
||||
sig, err := kp.sk.Sign(msg)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, sig)
|
||||
|
||||
ok := kp.sk.Public().Verify(msg, sig)
|
||||
require.True(t, ok)
|
||||
}
|
||||
|
||||
func TestSignature_Hex(t *testing.T) {
|
||||
kp, err := GenerateKeys()
|
||||
require.NoError(t, err)
|
||||
|
||||
msg := []byte("testmessage")
|
||||
sig, err := kp.sk.Sign(msg)
|
||||
require.NoError(t, err)
|
||||
|
||||
hex := sig.Hex()
|
||||
sig2, err := NewSignatureFromHex(hex)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, sig, sig2)
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package monero
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -5,12 +5,10 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/noot/atomic-swap/monero/crypto"
|
||||
"github.com/noot/atomic-swap/rpcclient"
|
||||
)
|
||||
|
||||
// Address represents a base58-encoded string
|
||||
type Address string
|
||||
|
||||
type generateFromKeysRequest struct {
|
||||
Filename string `json:"filename"`
|
||||
Address string `json:"address"`
|
||||
@@ -24,7 +22,7 @@ type generateFromKeysResponse struct {
|
||||
Info string `json:"info"`
|
||||
}
|
||||
|
||||
func (c *client) callGenerateFromKeys(sk *PrivateSpendKey, vk *PrivateViewKey, address Address,
|
||||
func (c *client) callGenerateFromKeys(sk *crypto.PrivateSpendKey, vk *crypto.PrivateViewKey, address crypto.Address,
|
||||
filename, password string) error {
|
||||
const (
|
||||
method = "generate_from_keys"
|
||||
|
||||
@@ -7,18 +7,20 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/noot/atomic-swap/common"
|
||||
"github.com/noot/atomic-swap/monero/crypto"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCallGenerateFromKeys(t *testing.T) {
|
||||
kp, err := GenerateKeys()
|
||||
kp, err := crypto.GenerateKeys()
|
||||
require.NoError(t, err)
|
||||
|
||||
r, err := rand.Int(rand.Reader, big.NewInt(999))
|
||||
require.NoError(t, err)
|
||||
|
||||
c := NewClient(common.DefaultBobMoneroEndpoint)
|
||||
err = c.callGenerateFromKeys(kp.sk, kp.vk, kp.Address(common.Mainnet), fmt.Sprintf("test-wallet-%d", r), "")
|
||||
err = c.callGenerateFromKeys(kp.SpendKey(), kp.ViewKey(), kp.Address(common.Mainnet),
|
||||
fmt.Sprintf("test-wallet-%d", r), "")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/noot/atomic-swap/common"
|
||||
"github.com/noot/atomic-swap/monero/crypto"
|
||||
|
||||
logging "github.com/ipfs/go-log"
|
||||
)
|
||||
@@ -43,7 +44,8 @@ func WaitForBlocks(client Client) error {
|
||||
}
|
||||
|
||||
// CreateMoneroWallet creates a monero wallet from a private keypair.
|
||||
func CreateMoneroWallet(name string, env common.Environment, client Client, kpAB *PrivateKeyPair) (Address, error) {
|
||||
func CreateMoneroWallet(name string, env common.Environment, client Client,
|
||||
kpAB *crypto.PrivateKeyPair) (crypto.Address, error) {
|
||||
t := time.Now().Format("2006-Jan-2-15:04:05")
|
||||
walletName := fmt.Sprintf("%s-%s", name, t)
|
||||
if err := client.GenerateFromKeys(kpAB, walletName, "", env); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user