From edae35a2912c040af8280f85fde33d332697407e Mon Sep 17 00:00:00 2001 From: nguyen-zung Date: Fri, 30 May 2025 23:27:06 +0700 Subject: [PATCH 1/2] add some structure for cardano --- wrapper/go-wrapper/core/coin.go | 1 + wrapper/go-wrapper/core/curve.go | 15 +++++ wrapper/go-wrapper/core/privateKey.go | 37 +++++++++++ wrapper/go-wrapper/core/publicKey.go | 14 +++- wrapper/go-wrapper/core/wallet.go | 1 + wrapper/go-wrapper/sample/cardano.go | 96 +++++++++++++++++++++++++++ 6 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 wrapper/go-wrapper/core/curve.go create mode 100644 wrapper/go-wrapper/core/privateKey.go create mode 100644 wrapper/go-wrapper/sample/cardano.go diff --git a/wrapper/go-wrapper/core/coin.go b/wrapper/go-wrapper/core/coin.go index 4ed1978b457..7d687dd422f 100644 --- a/wrapper/go-wrapper/core/coin.go +++ b/wrapper/go-wrapper/core/coin.go @@ -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 { diff --git a/wrapper/go-wrapper/core/curve.go b/wrapper/go-wrapper/core/curve.go new file mode 100644 index 00000000000..95130f859aa --- /dev/null +++ b/wrapper/go-wrapper/core/curve.go @@ -0,0 +1,15 @@ +package core + +// #cgo CFLAGS: -I../../../include +// #include +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 +) diff --git a/wrapper/go-wrapper/core/privateKey.go b/wrapper/go-wrapper/core/privateKey.go new file mode 100644 index 00000000000..11fa6e3af87 --- /dev/null +++ b/wrapper/go-wrapper/core/privateKey.go @@ -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 +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) +} diff --git a/wrapper/go-wrapper/core/publicKey.go b/wrapper/go-wrapper/core/publicKey.go index 6059189f9d4..b549b418fd2 100644 --- a/wrapper/go-wrapper/core/publicKey.go +++ b/wrapper/go-wrapper/core/publicKey.go @@ -5,13 +5,21 @@ package core // #include 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 { @@ -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) +} diff --git a/wrapper/go-wrapper/core/wallet.go b/wrapper/go-wrapper/core/wallet.go index 61866637d77..41619c73093 100644 --- a/wrapper/go-wrapper/core/wallet.go +++ b/wrapper/go-wrapper/core/wallet.go @@ -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") diff --git a/wrapper/go-wrapper/sample/cardano.go b/wrapper/go-wrapper/sample/cardano.go new file mode 100644 index 00000000000..358384a8fa4 --- /dev/null +++ b/wrapper/go-wrapper/sample/cardano.go @@ -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) +} From d1c16b3278588ae06eaf047a52fd8cdef4d13527 Mon Sep 17 00:00:00 2001 From: nguyen-zung Date: Fri, 30 May 2025 23:27:57 +0700 Subject: [PATCH 2/2] enable testing for Cardano --- wrapper/go-wrapper/main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/wrapper/go-wrapper/main.go b/wrapper/go-wrapper/main.go index 51487a56dfc..0680fd96bdf 100644 --- a/wrapper/go-wrapper/main.go +++ b/wrapper/go-wrapper/main.go @@ -52,6 +52,7 @@ func main() { fmt.Println("\t", btcTxn) sample.ExternalSigningDemo() + sample.TestCardano() } func createEthTransaction(ew *core.Wallet) string {