MCW is a Go package that provides a unified interface for managing wallets, generating mnemonics, and interacting with different blockchain networks: Ethereum, Solana, Bitcoin, and Aptos.The interface includes functionality for creating and managing wallets, handling transactions, and performing other blockchain-related operations.
go get github.com/tosynthegeek/mcw
go get github.com/tosynthegeek/mcw/walletImport the package in your Go code:
import "github.com/tosynthegeek/mcw/wallet"| Method | Ethereum | Solana | Bitcoin | Aptos | Flow |
|---|---|---|---|---|---|
| GenerateMnemonic | âś“ | âś“ | âś“ | âś“ | âś“ |
| WalletFromMnemonic | âś“ | âś“ | âś“ | âś“ | âś“ |
| CreateWallet | âś“ | âś“ | âś“ | âś“ | âś“ |
| GetAddressFromPrivateKey | âś“ | âś“ | âś“ | âś“ | âś— |
| GetBalance | âś“ | âś“ | âś“ | âś“ | âś“ |
| GetTokenBalance | âś“ | âś“ | âś— | âś“ | âś— |
| GetTxByHash | âś“ | âś“ | âś“ | âś“ | âś“ |
| Transfer | âś“ | âś“ | âś“ | âś“ | âś“ |
| TransferToken | âś“ | âś“ | âś— | âś— | âś— |
| GetTokenInfo | âś“ | âś“ | âś— | âś— | âś— |
| SmartContractCall | âś“ | âś— | âś— | âś— | âś— |
| CreateAccountCreationTx | âś— | âś— | âś— | âś— | âś“ |
Generates a BIP-39 mnemonic phrase based on the specified entropy bit size. EThe mnemonic phrase is generated based on a specific bit size of entropy (randomness). 128 bits of entropy gives a 12-word mnemonic. 160 bits of entropy gives a 15-word mnemonic. 192 bits of entropy gives an 18-word mnemonic. 224 bits of entropy gives a 21-word mnemonic. 256 bits of entropy gives a 24-word mnemonic.
bitsize:= 128
mnemonic, err := wallet.GenerateMnemonic(bitsize)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Mnemonic:", mnemonic)
}- Output
Mnemonic: abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about
WalletFromMnemonic generates a wallet for a specified network using a given mnemonic phrase and passphrase. It takes in mnemonic, passphrase and network in a types.WalletParam struct.
It supports Ethereum, Solana, Bitcoin, and Aptos
mnemonic := "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"
passphrase:= "mysecretpassword"
network:= "ethereum"
wp:= types.WalletParam {
Mnemonic: mnemonic,
Passphrase: passphrase,
Network: network,
}
wallet, err:= wallet.WalletFromMnemonic(wp)
if err != nil {
fmt.Println("Error:", err)
}
fmt.Printf("Mnemonic: %s\n", wallet.Mnemonic)
fmt.Printf("Private Key: %s\n", wallet.PrivateKey)
fmt.Printf("Public Key: %s\n", wallet.PublicKey)
fmt.Printf("Address: %s\n", wallet.Address)- Output:
Mnemonic: abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about,
PrivateKey: 5e62984d8bda6a40bbdb08496b1d3f6f5e1be8b1fe4a575d18b9e0f5934eac4d,
PublicKey: 0360ec40d4ec3132b3c5d6d9b4cddf8e17bb2c0e9e20d69e2e0bb9f9d7f9d20d6f,
Address: 0x1234567890123456789012345678901234567890CreateWallet generates a new wallet for a specified network. It takes in network and other parameters in a types.CWParam struct. It returns a Wallet struct containing the mnemonic, private key, public key, and address.
cwp := types.CWParam{
Network: "ethereum",
Passphrase: "mysecretpassword",
}
wallet, err := wallet.CreateWallet(cwp)
if err != nil {
fmt.Println("Error:", err)
}- Output
Mnemonic: abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about,
PrivateKey: 5e62984d8bda6a40bbdb08496b1d3f6f5e1be8b1fe4a575d18b9e0f5934eac4d,
PublicKey: 0360ec40d4ec3132b3c5d6d9b4cddf8e17bb2c0e9e20d69e2e0bb9f9d7f9d20d6f,
Address: 0x1234567890123456789012345678901234567890GetAddressFromPrivateKey derives the address from a given private key for a specified network. It takes in the network and private key as strings. It returns an Address struct.
It supports Ethereum, Solana, Bitcoin,and Aptos. There is no Flow support because Flow addresses aren't derived from private or public keys. In Flow, addresses are assigned by the network when an account is created.
network := "ethereum"
privateKey := "5e62984d8bda6a40bbdb08496b1d3f6f5e1be8b1fe4a575d18b9e0f5934eac4d"
address, err := wallet.GetAddressFromPrivateKey(network, privateKey)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Address:", address)
}- Output
Address: {
Address: "0x1234567890123456789012345678901234567890"
}Note: The actual address output will vary depending on the network and private key provided. Each supported blockchain (Ethereum, Solana, Bitcoin, and Aptos) has its own method of deriving addresses from private keys:
- Ethereum: Addresses are derived from the public key, which is in turn derived from the private key.
- Solana: Addresses are essentially the public key in base58 encoding.
- Bitcoin: Addresses are derived from the public key and can be in different formats (e.g., P2PKH, P2SH, Bech32).
- Aptos: Addresses are derived from the public key.
For Flow, addresses are assigned by the network when an account is created, not derived from keys. This is why the function doesn't support Flow addresses.
GetBalance retrieves the balance for a given address on a specified network. It takes in network, address, and other parameters in a types.BalanceParam struct. It returns a Balance struct.
It supports Ethereum, Solana, Bitcoin, Aptos, and Flow.
bp := types.BalanceParam{
Network: "ethereum",
Address: "0x1234567890123456789012345678901234567890",
EndpointURL: "http://dummy-ethereum-rpc.com:8545" // replace with your EndpointURL
// Add other necessary parameters
}
balance, err := wallet.GetBalance(bp)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Balance:", balance)
}- Output
Balance: {
Address: 0x1234567890123456789012345678901234567890
Balance: "1000000000000000000", // 1 ETH in wei
}GetTokenBalance retrieves the token balance for a given address and token on a specified network. It takes in network, address, token address, and other parameters in a types.TBParam struct. It returns a TokenBalance struct.
It supports Ethereum, Solana, and Aptos. There is no Flow and Bitcoin support yet.
tbp := types.TBParam{
Network: "solana",
EndpointURL: "rpc.MainnetRPCEndpoint"
Address: "GLHCm5rMasb1kX7M7QL6Q9SVRWPscXsXpw32bmYgT7xo",
TokenAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC token address
Context: context.TODO()
// Add other necessary parameters
}
tokenBalance, err := wallet.GetTokenBalance(tbp)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Token Balance:", tokenBalance)
}- Output
Token Balance: {
Address: GLHCm5rMasb1kX7M7QL6Q9SVRWPscXsXpw32bmYgT7xo
Data: 58.90
}GetTxByHash retrieves transaction details for a given transaction hash on a specified network. It takes in network, transaction hash, and other parameters in a types.HashParam struct. It returns a TransactionByHash struct.
It supports Ethereum, Solana, Bitcoin, Aptos, and Flow.
hp := types.HashParam{
Network: "ethereum",
Hash: "0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234",
// Add other necessary parameters
}
tx, err := wallet.GetTxByHash(hp)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Transaction:", tx)
}- Output
Transaction: {
isPending: false,
Transaction: {
}
}Transfer initiates a transfer of native currency on a specified network. It takes in network, from address, to address, amount, and other parameters in a types.TransferParam struct. It returns a TransferData struct.
It supports Ethereum, Solana, Bitcoin, Aptos, and Flow.
tp := types.TransferParam{
Network: "ethereum",
From: "0x1234567890123456789012345678901234567890",
To: "0x0987654321098765432109876543210987654321",
Amount: "1000000000000000000", // 1 ETH in wei
// Add other necessary parameters
}
transferData, err := wallet.Transfer(tp)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Transfer Data:", transferData)
}- Output
ash: 0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234,
Data: {
}TransferToken initiates a transfer of tokens on a specified network. It takes in network, from address, to address, token address, amount, and other parameters in a types.TransferTokenParam struct. It returns a TransferData struct.
It supports only Ethereum and Solana. There is no Bitcoin, Aptos, and Flow support yet.
ttp := types.TransferTokenParam{
Network: "ethereum",
From: "0x1234567890123456789012345678901234567890",
To: "0x0987654321098765432109876543210987654321",
TokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC token address
Amount: "1000000",
// Add other necessary parameters
}
transferData, err := wallet.TransferToken(ttp)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Transfer Data:", transferData)
}- Output
Transfer Data: {
TxHash: "0x123456789abcdef123456789abcdef123456789abcdef123456789abcdef1234",
Data: {
}
// Other transfer details
}GetTokenInfo retrieves information about a token on a specified network. It takes in network, token address, and other parameters in a types.TokenInfoParam struct. It returns a TokenInfo struct.
It supports only Ethereum and Solana. There is no Bitcoin, Aptos, and Flow support yet.
tip := types.TokenInfoParam{
Network: "ethereum",
TokenAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC token address
// Add other necessary parameters
}
tokenInfo, err := wallet.GetTokenInfo(tip)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Token Info:", tokenInfo)
}- Output
Token Info: {
Name: "USD Coin",
Symbol: "USDC",
Decimals: 6,
TotalSupply: "1000000000000000",
// Other token details
}SmartContractCall executes a smart contract function on a specified network. It takes in network, contract address, function name, parameters, and other details in a types.SmartContractCallPayload struct. It returns an interface{} which can be type-asserted to the expected return type.
It supports only Ethereum at the moment.
payload := types.SmartContractCallPayload{
Network: "ethereum",
ContractAddress: "0x1234567890123456789012345678901234567890",
FunctionName: "balanceOf",
Params: []interface{}{"0x0987654321098765432109876543210987654321"},
// Add other necessary parameters
}
result, err := wallet.SmartContractCall(payload)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}- Output
Result: 1000000000000000000CreateAccountCreationTx prepares a transaction to create a new Flow account and calculates the expected address for this account. It takes in a wallet, payer address, and network. It returns a pointer to the prepared transaction, the expected address of the new account, and an error if any.
This function is specific to the Flow blockchain.
Note: This function only prepares the transaction and calculates the expected address. The transaction still needs to be signed and submitted to the blockchain to actually create the account.
wallet := types.Wallet{
PublicKey: "0360ec40d4ec3132b3c5d6d9b4cddf8e17bb2c0e9e20d69e2e0bb9f9d7f9d20d6f",
// Other wallet details
}
payer := Flow.HexToAddress("0x1234567890123456")
network := Flow.Mainnet
tx, expectedAddress, err := wallet.CreateAccountCreationTx(wallet, payer, network)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Transaction:", tx)
fmt.Println("Expected Address:", expectedAddress)
}- Output
Transaction: {...} // Flow transaction object
Expected Address: 0x9876543210987654Errors in the interface are returned in Go's idiomatic way as the second return value. The error messages provide detailed information about what went wrong. The error ErrUnsupportedNetwork is returned when an unsupported network is specified.
var ErrUnsupportedNetwork = errors.New(
"unsupported network: the specified network is not recognized. Please ensure that the network name is correct and supported by the application."
)Open to contributions. Couple of contributions to be made. Check out the contribution guidelines