Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions wrapper/go-wrapper/core/coin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const (
CoinTypeBinance CoinType = C.TWCoinTypeBinance
CoinTypeEthereum CoinType = C.TWCoinTypeEthereum
CoinTypeTron CoinType = C.TWCoinTypeTron
CoinTypeCardano CoinType = C.TWCoinTypeCardano
)

func (c CoinType) GetName() string {
Expand Down
15 changes: 15 additions & 0 deletions wrapper/go-wrapper/core/curve.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package core

// #cgo CFLAGS: -I../../../include
// #include <TrustWalletCore/TWCurve.h>
import "C"

type CurveType uint32

const (
CurveSECP256k1 CurveType = C.TWCurveSECP256k1
CurveED25519 CurveType = C.TWCurveED25519
CurveCurve25519 CurveType = C.TWCurveCurve25519
CurveED25519ExtendedCardano CurveType = C.TWCurveED25519ExtendedCardano
CurveNone CurveType = C.TWCurveNone
)
37 changes: 37 additions & 0 deletions wrapper/go-wrapper/core/privateKey.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package core

// #cgo CFLAGS: -I../../../include
// #cgo LDFLAGS: -L../../../build -L../../../build/local/lib -L../../../build/trezor-crypto -lTrustWalletCore -lwallet_core_rs -lprotobuf -lTrezorCrypto -lstdc++ -lm
// #include <TrustWalletCore/TWPrivateKey.h>
import "C"

import (
"fmt"
"unsafe"

"github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/types"
)

type TWPrivateKey *C.struct_TWPrivateKey

func PrivateKeyCreateWithData(key []byte) (TWPrivateKey, error) {
keyData := types.TWDataCreateWithGoBytes(key)
defer C.TWDataDelete(keyData)
privateKey := C.TWPrivateKeyCreateWithData(keyData)
if privateKey == nil {
return nil, fmt.Errorf("invalid private key")
}
return privateKey, nil
}

func PrivateKeyDelete(key TWPrivateKey) {
C.TWPrivateKeyDelete(nil)
}

func PrivateKeySign(key TWPrivateKey, in unsafe.Pointer, curve CurveType) unsafe.Pointer {
return C.TWPrivateKeySign(key, in, C.enum_TWCurve(curve))
}

func TWPrivateKeyGetPublicKeyEd25519Cardano(key TWPrivateKey) TWPublicKey {
return C.TWPrivateKeyGetPublicKeyEd25519Cardano(key)
}
14 changes: 13 additions & 1 deletion wrapper/go-wrapper/core/publicKey.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@ package core
// #include <TrustWalletCore/TWPublicKey.h>
import "C"

import "github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/types"
import (
"unsafe"

"github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/types"
)

type PublicKeyType uint32

type TWPublicKey *C.struct_TWPublicKey

const (
PublicKeyTypeSECP256k1 PublicKeyType = C.TWPublicKeyTypeSECP256k1
PublicKeyTypeSECP256k1Extended PublicKeyType = C.TWPublicKeyTypeSECP256k1Extended
PublicKeyTypeED25519Cardano PublicKeyType = C.TWPublicKeyTypeED25519Cardano
PublicKeyTypeED25519 PublicKeyType = C.TWPublicKeyTypeED25519
)

func PublicKeyVerify(key []byte, keyType PublicKeyType, signature []byte, message []byte) bool {
Expand Down Expand Up @@ -39,3 +47,7 @@ func PublicKeyVerifyAsDER(key []byte, keyType PublicKeyType, signature []byte, m

return bool(C.TWPublicKeyVerifyAsDER(publicKey, sig, msg))
}

func PublicKeyDescription(key TWPublicKey) unsafe.Pointer {
return C.TWPublicKeyDescription(key)
}
1 change: 1 addition & 0 deletions wrapper/go-wrapper/core/wallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type Wallet struct {
CoinType
}

// Using with secp256k1
func CreateWalletWithMnemonic(mn string, ct CoinType) (*Wallet, error) {
if !IsMnemonicValid(mn) {
return nil, errors.New("mnemonic is not valid")
Expand Down
1 change: 1 addition & 0 deletions wrapper/go-wrapper/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ func main() {
fmt.Println("\t", btcTxn)

sample.ExternalSigningDemo()
sample.TestCardano()
}

func createEthTransaction(ew *core.Wallet) string {
Expand Down
96 changes: 96 additions & 0 deletions wrapper/go-wrapper/sample/cardano.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package sample

import (
"encoding/hex"
"errors"

"github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/core"
"github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/protos/cardano"
"github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/protos/transactioncompiler"
"github.com/Cramiumlabs/wallet-core/wrapper/go-wrapper/types"
"google.golang.org/protobuf/proto"
)

// Using real succesfull transation:
func TestCardano() {
txHash1, _ := hex.DecodeString("8316e5007d61fb90652cabb41141972a38b5bc60954d602cf843476aa3f67f63")
utxo1 := cardano.TxInput{
OutPoint: &cardano.OutPoint{
TxHash: txHash1,
OutputIndex: 0,
},
Address: "Ae2tdPwUPEZ6vkqxSjJxaQYmDxHf5DTnxtZ67pFLJGTb9LTnCGkDP6ca3f8",
Amount: 2500000,
}

txHash2, _ := hex.DecodeString("e29392c59c903fefb905730587d22cae8bda30bd8d9aeec3eca082ae77675946")
utxo2 := cardano.TxInput{
OutPoint: &cardano.OutPoint{
TxHash: txHash2,
OutputIndex: 0,
},
Address: "Ae2tdPwUPEZ6vkqxSjJxaQYmDxHf5DTnxtZ67pFLJGTb9LTnCGkDP6ca3f8",
Amount: 1700000,
}

transferMessage := cardano.Transfer{
ToAddress: "addr1q90uh2eawrdc9vaemftgd50l28yrh9lqxtjjh4z6dnn0u7ggasexxdyyk9f05atygnjlccsjsggtc87hhqjna32fpv5qeq96ls",
ChangeAddress: "addr1qx55ymlqemndq8gluv40v58pu76a2tp4mzjnyx8n6zrp2vtzrs43a0057y0edkn8lh9su8vh5lnhs4npv6l9tuvncv8swc7t08",
Amount: 3000000,
UseMaxAmount: false,
}
var privateKeys [][]byte
privateKeyData, _ := hex.DecodeString("98f266d1aac660179bc2f456033941238ee6b2beb8ed0f9f34c9902816781f5a9903d1d395d6ab887b65ea5e344ef09b449507c21a75f0ce8c59d0ed1c6764eba7f484aa383806735c46fd769c679ee41f8952952036a6e2338ada940b8a91f4e890ca4eb6bec44bf751b5a843174534af64d6ad1f44e0613db78a7018781f5aa151d2997f52059466b715d8eefab30a78b874ae6ef4931fa58bb21ef8ce2423d46f19d0fbf75afb0b9a24e31d533f4fd74cee3b56e162568e8defe37123afc4")
privateKeys = append(privateKeys, privateKeyData)

input := cardano.SigningInput{
Utxos: []*cardano.TxInput{&utxo1, &utxo2},
PrivateKey: privateKeys,
TransferMessage: &transferMessage,
Ttl: 190000000,
}

txInputData, _ := proto.Marshal(&input)
msgForSign := core.PreImageHashes(core.CoinTypeCardano, txInputData)

var preSigningOutput transactioncompiler.PreSigningOutput
proto.Unmarshal(msgForSign, &preSigningOutput)

var output cardano.SigningOutput
err := core.CreateSignedTx(&input, core.CoinTypeCardano, &output)
if err != nil {
panic(err)
}

twPrivateKey, err := core.PrivateKeyCreateWithData(privateKeyData)
if err != nil {
panic(err)
}

dataForSign := types.TWDataCreateWithGoBytes(preSigningOutput.DataHash)
signature := core.PrivateKeySign(twPrivateKey, dataForSign, core.CurveED25519ExtendedCardano)
if signature == nil {
panic(errors.New("signature is nil"))
}

pub := core.TWPrivateKeyGetPublicKeyEd25519Cardano(twPrivateKey)
if pub == nil {
panic(errors.New("publickey pointer is nil"))
}

pubValue := core.PublicKeyDescription(pub)
if pubValue == nil {
panic(errors.New("no value for publickey"))
}

pubKeyBytes, _ := hex.DecodeString(types.TWStringGoString(pubValue))
if pubKeyBytes == nil {
panic(errors.New("no value for publickey"))
}

valid := core.PublicKeyVerify(pubKeyBytes, core.PublicKeyTypeED25519Cardano, types.TWDataGoBytes(signature), preSigningOutput.DataHash)
if !valid {
panic(errors.New("verification failed"))
}
core.PrivateKeyDelete(twPrivateKey)
}