Merge branch 'blockvision_main'
This commit is contained in:
10
constant/intent.go
Normal file
10
constant/intent.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package constant
|
||||||
|
|
||||||
|
type IntentScope = uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
TransactionDataIntentScope IntentScope = 0
|
||||||
|
TransactionEffectsIntentScope IntentScope = 1
|
||||||
|
CheckpointSummaryIntentScope IntentScope = 2
|
||||||
|
PersonalMessageIntentScope IntentScope = 3
|
||||||
|
)
|
||||||
27
models/intent.go
Normal file
27
models/intent.go
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
import "github.com/block-vision/sui-go-sdk/constant"
|
||||||
|
|
||||||
|
type AppId int
|
||||||
|
|
||||||
|
const (
|
||||||
|
Sui AppId = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
type IntentVersion int
|
||||||
|
|
||||||
|
const (
|
||||||
|
V0 IntentVersion = 0
|
||||||
|
)
|
||||||
|
|
||||||
|
func IntentWithScope(intentScope constant.IntentScope) []int {
|
||||||
|
return []int{int(intentScope), int(V0), int(Sui)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMessageWithIntent(message []byte, scope constant.IntentScope) []byte {
|
||||||
|
intent := []byte{scope, 0, 0}
|
||||||
|
intentMessage := make([]byte, len(intent)+len(message))
|
||||||
|
copy(intentMessage, intent)
|
||||||
|
copy(intentMessage[len(intent):], message)
|
||||||
|
return intentMessage
|
||||||
|
}
|
||||||
@@ -5,9 +5,13 @@ import (
|
|||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"golang.org/x/crypto/blake2b"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/block-vision/sui-go-sdk/constant"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/blake2b"
|
||||||
)
|
)
|
||||||
|
|
||||||
type InputObjectKind map[string]interface{}
|
type InputObjectKind map[string]interface{}
|
||||||
@@ -38,6 +42,12 @@ type HexData struct {
|
|||||||
data []byte
|
data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SignaturePubkeyPair struct {
|
||||||
|
SignatureScheme string
|
||||||
|
Signature []byte
|
||||||
|
PubKey []byte
|
||||||
|
}
|
||||||
|
|
||||||
func NewHexData(str string) (*HexData, error) {
|
func NewHexData(str string) (*HexData, error) {
|
||||||
if strings.HasPrefix(str, "0x") || strings.HasPrefix(str, "0X") {
|
if strings.HasPrefix(str, "0x") || strings.HasPrefix(str, "0X") {
|
||||||
str = str[2:]
|
str = str[2:]
|
||||||
@@ -113,7 +123,7 @@ func (txn *TxnMetaData) SignSerializedSigWith(privateKey ed25519.PrivateKey) *Si
|
|||||||
}
|
}
|
||||||
return &SignedTransactionSerializedSig{
|
return &SignedTransactionSerializedSig{
|
||||||
TxBytes: txn.TxBytes,
|
TxBytes: txn.TxBytes,
|
||||||
Signature: toSerializedSignature(sigBytes, privateKey.Public().(ed25519.PublicKey)),
|
Signature: ToSerializedSignature(sigBytes, privateKey.Public().(ed25519.PublicKey)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +135,7 @@ func messageWithIntent(message []byte) []byte {
|
|||||||
return intentMessage
|
return intentMessage
|
||||||
}
|
}
|
||||||
|
|
||||||
func toSerializedSignature(signature, pubKey []byte) string {
|
func ToSerializedSignature(signature, pubKey []byte) string {
|
||||||
signatureLen := len(signature)
|
signatureLen := len(signature)
|
||||||
pubKeyLen := len(pubKey)
|
pubKeyLen := len(pubKey)
|
||||||
serializedSignature := make([]byte, 1+signatureLen+pubKeyLen)
|
serializedSignature := make([]byte, 1+signatureLen+pubKeyLen)
|
||||||
@@ -134,3 +144,76 @@ func toSerializedSignature(signature, pubKey []byte) string {
|
|||||||
copy(serializedSignature[1+signatureLen:], pubKey)
|
copy(serializedSignature[1+signatureLen:], pubKey)
|
||||||
return base64.StdEncoding.EncodeToString(serializedSignature)
|
return base64.StdEncoding.EncodeToString(serializedSignature)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FromSerializedSignature(serializedSignature string) (*SignaturePubkeyPair, error) {
|
||||||
|
_bytes, err := base64.StdEncoding.DecodeString(serializedSignature)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
signatureScheme := parseSignatureScheme(_bytes[0])
|
||||||
|
if strings.EqualFold(serializedSignature, "") {
|
||||||
|
return nil, fmt.Errorf("multiSig is not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
signature := _bytes[1 : len(_bytes)-32]
|
||||||
|
pubKeyBytes := _bytes[1+len(signature):]
|
||||||
|
|
||||||
|
keyPair := &SignaturePubkeyPair{
|
||||||
|
SignatureScheme: signatureScheme,
|
||||||
|
Signature: signature,
|
||||||
|
PubKey: pubKeyBytes,
|
||||||
|
}
|
||||||
|
return keyPair, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseSignatureScheme(scheme byte) string {
|
||||||
|
switch scheme {
|
||||||
|
case 0:
|
||||||
|
return "ED25519"
|
||||||
|
case 1:
|
||||||
|
return "Secp256k1"
|
||||||
|
case 2:
|
||||||
|
return "Secp256r1"
|
||||||
|
case 3:
|
||||||
|
return "MultiSig"
|
||||||
|
default:
|
||||||
|
return "ED25519"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerifyPersonalMessage(message string, signature string) (signer string, pass bool, err error) {
|
||||||
|
b64Message := base64.StdEncoding.EncodeToString([]byte(message))
|
||||||
|
return VerifyMessage(b64Message, signature, constant.PersonalMessageIntentScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerifyTransaction(b64Message string, signature string) (signer string, pass bool, err error) {
|
||||||
|
return VerifyMessage(b64Message, signature, constant.TransactionDataIntentScope)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerifyMessage(message, signature string, scope constant.IntentScope) (signer string, pass bool, err error) {
|
||||||
|
b64Bytes, _ := base64.StdEncoding.DecodeString(message)
|
||||||
|
messageBytes := NewMessageWithIntent(b64Bytes, scope)
|
||||||
|
|
||||||
|
serializedSignature, err := FromSerializedSignature(signature)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, err
|
||||||
|
}
|
||||||
|
digest := blake2b.Sum256(messageBytes)
|
||||||
|
|
||||||
|
pass = ed25519.Verify(serializedSignature.PubKey[:], digest[:], serializedSignature.Signature)
|
||||||
|
|
||||||
|
signer = Ed25519PublicKeyToSuiAddress(serializedSignature.PubKey)
|
||||||
|
if err != nil {
|
||||||
|
return "", false, fmt.Errorf("invalid signer %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Ed25519PublicKeyToSuiAddress(pubKey []byte) string {
|
||||||
|
newPubkey := []byte{byte(SigFlagEd25519)}
|
||||||
|
newPubkey = append(newPubkey, pubKey...)
|
||||||
|
|
||||||
|
addrBytes := blake2b.Sum256(newPubkey)
|
||||||
|
return fmt.Sprintf("0x%s", hex.EncodeToString(addrBytes[:])[:64])
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
package signer
|
|
||||||
|
|
||||||
type AppId int
|
|
||||||
|
|
||||||
const (
|
|
||||||
Sui AppId = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
type IntentVersion int
|
|
||||||
|
|
||||||
const (
|
|
||||||
V0 IntentVersion = 0
|
|
||||||
)
|
|
||||||
|
|
||||||
type IntentScope int
|
|
||||||
|
|
||||||
const (
|
|
||||||
TransactionData IntentScope = 0
|
|
||||||
TransactionEffects IntentScope = 1
|
|
||||||
CheckpointSummary IntentScope = 2
|
|
||||||
PersonalMessage IntentScope = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
func IntentWithScope(intentScope IntentScope) []int {
|
|
||||||
return []int{int(intentScope), int(V0), int(Sui)}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
package signer
|
package signer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
||||||
"github.com/block-vision/sui-go-sdk/common/keypair"
|
"github.com/block-vision/sui-go-sdk/common/keypair"
|
||||||
|
"github.com/block-vision/sui-go-sdk/constant"
|
||||||
|
"github.com/block-vision/sui-go-sdk/models"
|
||||||
"github.com/tyler-smith/go-bip39"
|
"github.com/tyler-smith/go-bip39"
|
||||||
"golang.org/x/crypto/blake2b"
|
"golang.org/x/crypto/blake2b"
|
||||||
)
|
)
|
||||||
@@ -49,3 +54,42 @@ func NewSignertWithMnemonic(mnemonic string) (*Signer, error) {
|
|||||||
}
|
}
|
||||||
return NewSigner(key.Key), nil
|
return NewSigner(key.Key), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SignedMessageSerializedSig struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
Signature string `json:"signature"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signer) SignMessage(data string, scope constant.IntentScope) (*SignedMessageSerializedSig, error) {
|
||||||
|
txBytes, _ := base64.StdEncoding.DecodeString(data)
|
||||||
|
message := models.NewMessageWithIntent(txBytes, scope)
|
||||||
|
digest := blake2b.Sum256(message)
|
||||||
|
var noHash crypto.Hash
|
||||||
|
sigBytes, err := s.PriKey.Sign(nil, digest[:], noHash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ret := &SignedMessageSerializedSig{
|
||||||
|
Message: data,
|
||||||
|
Signature: models.ToSerializedSignature(sigBytes, s.PriKey.Public().(ed25519.PublicKey)),
|
||||||
|
}
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signer) SignTransaction(b64TxBytes string) (*models.SignedTransactionSerializedSig, error) {
|
||||||
|
result, err := s.SignMessage(b64TxBytes, constant.PersonalMessageIntentScope)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.SignedTransactionSerializedSig{
|
||||||
|
TxBytes: result.Message,
|
||||||
|
Signature: result.Signature,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Signer) SignPersonalMessage(message string) (*SignedMessageSerializedSig, error) {
|
||||||
|
b64Message := base64.StdEncoding.EncodeToString([]byte(message))
|
||||||
|
return s.SignMessage(b64Message, constant.PersonalMessageIntentScope)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user