Skip to content
Draft
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
3 changes: 1 addition & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
[build]
remap-debuginfo = true
[build]
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ panic = "abort"
lto = true
codegen-units = 1
rpath = false
opt-level = "z"
overflow-checks = false

[[example]]
name = "test_c_interface"
Expand Down
35 changes: 26 additions & 9 deletions build_rust.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ declare -A TARGETS=(
export MACOSX_DEPLOYMENT_TARGET=15.0
export CARGO_NET_GIT_FETCH_WITH_CLI=true # faster CI clones

# Control whether to copy dynamic libraries (.dll, .dylib, .so) and Windows import libraries (*.dll.a, *.dll.lib)
# By default only static libraries (.a, .lib) are copied, excluding Windows import libraries
COPY_DYNAMIC_LIBS="${COPY_DYNAMIC_LIBS:-true}"

CARGO_HOME="${CARGO_HOME:-$HOME/.cargo}"
export RUSTFLAGS="--remap-path-prefix=$CARGO_HOME=/cargo --remap-path-prefix=$HOME=/home/user --remap-path-prefix=$ROOT=/build ${RUSTFLAGS:-}"

for key in "${!TARGETS[@]}"; do
triple="${TARGETS[$key]}"
echo -e "\n=== Building $key → $triple ==="
Expand All @@ -33,18 +40,28 @@ for key in "${!TARGETS[@]}"; do
dst="$OUT/$key"
mkdir -p "$dst"

if [ "$triple" == "darwin_amd64" ] || [ "$triple" == "darwin_arm64" ]; then
install_name_tool -id @rpath/libsigner_go.dylib \
target/$triple/release/deps/libsigner_go.dylib
fi

# Copy all signer_go and libsigner_go files (.lib, .dll, .a)
# Copy all signer_go and libsigner_go files
find "target/$triple/release/" -name "signer_go*" -o -name "libsigner_go*" | while read -r file; do
if [ -f "$file" ] && [[ "$file" =~ \.(lib|dll|a|dylib|so)$ ]]; then
cp "$file" "$dst/"
echo " Copied: $(basename "$file")"
if [ -f "$file" ]; then
# Copy static libraries (but exclude Windows import libraries *.dll.a, *.dll.lib)
if [[ "$file" =~ \.(lib|a)$ ]] && [[ ! "$file" =~ \.dll\.(lib|a)$ ]]; then
cp "$file" "$dst/"
echo " Copied: $(basename "$file")"
# Copy dynamic libraries and Windows import libraries only if enabled
elif [[ "$COPY_DYNAMIC_LIBS" == "true" ]] && [[ "$file" =~ \.(dll|dylib|so|dll\.a|dll\.lib)$ ]]; then
cp "$file" "$dst/"
echo " Copied: $(basename "$file")"
fi
fi
done

# Fix install_name for macOS dylibs AFTER copying (only if dynamic libs are enabled)
if [[ "$COPY_DYNAMIC_LIBS" == "true" ]] && ([[ "$key" == "darwin_amd64" ]] || [[ "$key" == "darwin_arm64" ]]); then
if [ -f "$dst/libsigner_go.dylib" ]; then
install_name_tool -id @rpath/libsigner_go.dylib "$dst/libsigner_go.dylib"
echo " Fixed install_name for $dst/libsigner_go.dylib"
fi
fi
done

echo -e "\n✅ All artifacts are in $(realpath "$OUT")"
Binary file modified prebuilt/darwin_amd64/libsigner_go.a
Binary file not shown.
Binary file modified prebuilt/darwin_amd64/libsigner_go.dylib
Binary file not shown.
Binary file modified prebuilt/darwin_arm64/libsigner_go.a
Binary file not shown.
Binary file modified prebuilt/darwin_arm64/libsigner_go.dylib
Binary file not shown.
Binary file modified prebuilt/linux_amd64/libsigner_go.a
Binary file not shown.
Binary file modified prebuilt/linux_amd64/libsigner_go.so
Binary file not shown.
Binary file modified prebuilt/linux_arm64/libsigner_go.a
Binary file not shown.
Binary file modified prebuilt/linux_arm64/libsigner_go.so
Binary file not shown.
Binary file modified prebuilt/windows_amd64/libsigner_go.a
Binary file not shown.
Binary file modified prebuilt/windows_amd64/libsigner_go.dll.a
Binary file not shown.
Binary file modified prebuilt/windows_amd64/signer_go.dll
Binary file not shown.
4 changes: 2 additions & 2 deletions signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ package signer
#cgo linux,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/linux_amd64 -lsigner_go -ldl -lpthread
#cgo linux,arm64 LDFLAGS: -L${SRCDIR}/prebuilt/linux_arm64 -lsigner_go -ldl -lpthread

#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/darwin_amd64 -lsigner_go -framework Security -framework CoreFoundation
#cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/prebuilt/darwin_arm64 -lsigner_go -framework Security -framework CoreFoundation
#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/darwin_amd64 -lsigner_go -framework Security -framework CoreFoundation -Wl,-rpath,${SRCDIR}/prebuilt/darwin_amd64
#cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/prebuilt/darwin_arm64 -lsigner_go -framework Security -framework CoreFoundation -Wl,-rpath,${SRCDIR}/prebuilt/darwin_arm64

#cgo windows,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/windows_amd64 -lsigner_go -lws2_32 -lbcrypt

Expand Down
113 changes: 113 additions & 0 deletions signer.go.manual_backup
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package signer

/*
#cgo CFLAGS: -I${SRCDIR}/include
#cgo linux,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/linux_amd64 -lsigner_go -ldl -lpthread
#cgo linux,arm64 LDFLAGS: -L${SRCDIR}/prebuilt/linux_arm64 -lsigner_go -ldl -lpthread

#cgo darwin,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/darwin_amd64 -lsigner_go -framework Security -framework CoreFoundation -Wl,-rpath,${SRCDIR}/prebuilt/darwin_amd64
#cgo darwin,arm64 LDFLAGS: -L${SRCDIR}/prebuilt/darwin_arm64 -lsigner_go -framework Security -framework CoreFoundation -Wl,-rpath,${SRCDIR}/prebuilt/darwin_arm64

#cgo windows,amd64 LDFLAGS: -L${SRCDIR}/prebuilt/windows_amd64 -lsigner_go -lws2_32 -lbcrypt



#include <stdlib.h>
#include "signer.h"
*/
import "C"
import (
"errors"
"unsafe"
)

// Signer represents a cryptographic signer
type Signer struct {
ptr *C.CSigner
}

// NewMnemonicSigner creates a new signer from a mnemonic phrase
func NewMnemonicSigner(mnemonicPhrase, derivationPath string) (*Signer, error) {
cMnemonic := C.CString(mnemonicPhrase)
defer C.free(unsafe.Pointer(cMnemonic))

cDerivationPath := C.CString(derivationPath)
defer C.free(unsafe.Pointer(cDerivationPath))

ptr := C.signer_new_mnemonic(cMnemonic, cDerivationPath)
if ptr == nil {
return nil, errors.New("failed to create mnemonic signer")
}

return &Signer{ptr: ptr}, nil
}

// NewBech32Signer creates a new signer from a root private key (bech32)
func NewBech32Signer(rootPrivateKey, derivationPath string) (*Signer, error) {
cRootPrivateKey := C.CString(rootPrivateKey)
defer C.free(unsafe.Pointer(cRootPrivateKey))

cDerivationPath := C.CString(derivationPath)
defer C.free(unsafe.Pointer(cDerivationPath))

ptr := C.signer_new_bech32(cRootPrivateKey, cDerivationPath)
if ptr == nil {
return nil, errors.New("failed to create bech32 signer")
}

return &Signer{ptr: ptr}, nil
}

// NewCLISigner creates a new signer from an ED25519 key (CLI style)
func NewCLISigner(ed25519Key string) (*Signer, error) {
cED25519Key := C.CString(ed25519Key)
defer C.free(unsafe.Pointer(cED25519Key))

ptr := C.signer_new_cli(cED25519Key)
if ptr == nil {
return nil, errors.New("failed to create CLI signer")
}

return &Signer{ptr: ptr}, nil
}

// SignTransaction signs a transaction and returns the signature
func (s *Signer) SignTransaction(txHex string) (string, error) {
if s.ptr == nil {
return "", errors.New("signer is nil")
}

cTxHex := C.CString(txHex)
defer C.free(unsafe.Pointer(cTxHex))

cSignature := C.signer_sign_transaction(s.ptr, cTxHex)
if cSignature == nil {
return "", errors.New("failed to sign transaction")
}
defer C.signer_free_string(cSignature)

return C.GoString(cSignature), nil
}

// GetPublicKey returns the public key as a hex string
func (s *Signer) GetPublicKey() (string, error) {
if s.ptr == nil {
return "", errors.New("signer is nil")
}

cPublicKey := C.signer_get_public_key(s.ptr)
if cPublicKey == nil {
return "", errors.New("failed to get public key")
}
defer C.signer_free_string(cPublicKey)

return C.GoString(cPublicKey), nil
}

// Close frees the signer resources
func (s *Signer) Close() {
if s.ptr != nil {
C.signer_free(s.ptr)
s.ptr = nil
}
}