Skip to content

Commit

Permalink
worked on sending the sepholia through this application
Browse files Browse the repository at this point in the history
  • Loading branch information
ibilalkayy committed Jun 26, 2024
1 parent 32aef99 commit 95a994a
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 36 deletions.
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
"github.com/spf13/cobra"
)

const version = "v0.2.1"
const version = "v0.2.2"

// rootCmd represents the base command when called without any subcommands
var RootCmd = &cobra.Command{
Expand Down
11 changes: 3 additions & 8 deletions cmd/spend/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/ibilalkayy/flow/cmd"
spend_handler "github.com/ibilalkayy/flow/cmd/spend/handler"
conversion "github.com/ibilalkayy/flow/common"
"github.com/ibilalkayy/flow/framework/blockchain"
"github.com/ibilalkayy/flow/framework/db"
"github.com/ibilalkayy/flow/framework/db/budget_db"
"github.com/ibilalkayy/flow/framework/db/total_amount_db"
Expand Down Expand Up @@ -57,19 +56,14 @@ var SpendCmd = &cobra.Command{
Use: "spend",
Short: "Spending money on various categories",
Run: func(cmd *cobra.Command, args []string) {
client, err := blockchain.NewClient()
if err != nil {
log.Fatalf("Failed to create blockchain client: %v", err)
}
fmt.Println(client)

categoryName, _ := cmd.Flags().GetString("category")
spendingAmount, _ := cmd.Flags().GetString("amount")
recipientAddress, _ := cmd.Flags().GetString("recipient-address")

h := TakeHandler()
spendingAmountInt := h.Deps.Common.StringToInt(spendingAmount)
if len(categoryName) != 0 && spendingAmountInt != 0 {
err := h.Deps.SpendAmount.SpendMoney(categoryName, spendingAmountInt)
err := h.Deps.SpendAmount.SpendMoney(categoryName, recipientAddress, spendingAmountInt)
if err != nil {
log.Fatal(err)
}
Expand All @@ -87,4 +81,5 @@ func init() {
// Flags
SpendCmd.Flags().StringP("category", "c", "", "Write the category name to spend the money on")
SpendCmd.Flags().StringP("amount", "a", "", "Write the spending amount for a category")
SpendCmd.Flags().StringP("recipient-address", "r", "", "Write the recipient address to send money")
}
13 changes: 6 additions & 7 deletions entities/history.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package entities

type HistoryVariables struct {
Date string
Time string
Category string
Amount int
TransactionID string
Blockchain string
Address string
Date string
Time string
Category string
Amount int
Blockchain string
RecipientAddress string
}
1 change: 1 addition & 0 deletions entities/spend.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type SpendingVariables struct {
Category string
CategoryName string
TotalAmountStatus string
RecipientAddress string
IncludedCatogeries [][2]string
TotalAmount int
SpendingAmount int
Expand Down
91 changes: 91 additions & 0 deletions framework/blockchain/client.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package blockchain

import (
"context"
"crypto/ecdsa"
"fmt"
"log"
"math/big"
"net/http"
"os"
"time"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/joho/godotenv"
coingecko "github.com/superoo7/go-gecko/v3"
)

type Client struct {
Expand Down Expand Up @@ -42,3 +50,86 @@ func NewClient() (*Client, error) {

return &Client{ethClient: ethClient, privateKey: privateKey}, nil
}

func (c *Client) getExchangeRate() (float64, error) {
httpClient := &http.Client{
Timeout: time.Second * 10,
}
cg := coingecko.NewClient(httpClient)
simpleSinglePrice, err := cg.SimpleSinglePrice("ethereum", "usd")
if err != nil {
return 0, fmt.Errorf("failed to get exchange rate: %v", err)
}
return float64(simpleSinglePrice.MarketPrice), nil
}

func (c *Client) ConvertUSDtoETH(usdAmount float64) (*big.Int, error) {
rate, err := c.getExchangeRate()
if err != nil {
return nil, err
}
ethAmount := usdAmount / rate
ethAmountWei := new(big.Float).Mul(big.NewFloat(ethAmount), big.NewFloat(1e18))
ethAmountBigInt := new(big.Int)
ethAmountWei.Int(ethAmountBigInt)
return ethAmountBigInt, nil
}

func (c *Client) AllocateFunds(toAddress string, amount *big.Int) (string, error) {
publicKey := c.privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
return "", fmt.Errorf("error casting public key to ECDSA")
}

fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
nonce, err := c.ethClient.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
return "", err
}

gasLimit := uint64(21000)
gasPrice, err := c.ethClient.SuggestGasPrice(context.Background())
if err != nil {
return "", err
}

to := common.HexToAddress(toAddress)
tx := types.NewTransaction(nonce, to, amount, gasLimit, gasPrice, nil)

chainID, err := c.ethClient.NetworkID(context.Background())
if err != nil {
return "", err
}

signedTx, err := types.SignTx(tx, types.NewEIP155Signer(chainID), c.privateKey)
if err != nil {
return "", err
}

err = c.ethClient.SendTransaction(context.Background(), signedTx)
if err != nil {
return "", err
}

fmt.Printf("tx sent: %s", signedTx.Hash().Hex())
return signedTx.Hash().Hex(), nil
}

func SpendFunds(usdAmount float64, recipientAddress string) {
client, err := NewClient()
if err != nil {
log.Fatalf("Failed to create blockchain client: %v", err)
}

ethAmount, err := client.ConvertUSDtoETH(usdAmount)
if err != nil {
log.Fatalf("Failed to convert USD to ETH: %v", err)
}

txHash, err := client.AllocateFunds(recipientAddress, ethAmount)
if err != nil {
log.Fatalf("Failed to allocate funds: %v", err)
}
fmt.Printf("Funds allocated with tx hash: %s\n", txHash)
}
14 changes: 7 additions & 7 deletions framework/db/budget_db/history_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func (h MyBudgetDB) InsertHistory(hv *entities.HistoryVariables) error {
return err
}

query := "INSERT INTO History(dates, timez, categories, amounts, transaction_ids, blockchains, addresses) VALUES($1, $2, $3, $4, $5, $6, $7)"
query := "INSERT INTO History(dates, timez, categories, amounts, blockchains, addresses) VALUES($1, $2, $3, $4, $5, $6)"
insert, err := data.Prepare(query)
if err != nil {
return err
Expand All @@ -34,7 +34,7 @@ func (h MyBudgetDB) InsertHistory(hv *entities.HistoryVariables) error {

if len(hv.Category) != 0 && len(includedCategory) != 0 {
if hv.Amount != 0 && totalAmount != 0 {
_, err = insert.Exec(hv.Date, hv.Time, hv.Category, hv.Amount, hv.TransactionID, hv.Blockchain, hv.Address)
_, err = insert.Exec(hv.Date, hv.Time, hv.Category, hv.Amount, hv.Blockchain, hv.RecipientAddress)
if err != nil {
return err
}
Expand All @@ -58,14 +58,14 @@ func (h MyBudgetDB) ViewHistory(category string) ([2]interface{}, error) {
defer db.Close()

tw := table.NewWriter()
tw.AppendHeader(table.Row{"Date", "Time", "Category", "Amounts", "Transaction IDs", "Blockchains", "Addresses"})
tw.AppendHeader(table.Row{"Date", "Time", "Category", "Amounts", "Blockchains", "Addresses"})

var rows *sql.Rows
if len(category) != 0 {
query := "SELECT dates, timez, categories, amounts, transaction_ids, blockchains, addresses from History WHERE categories=$1"
query := "SELECT dates, timez, categories, amounts, blockchains, addresses from History WHERE categories=$1"
rows, err = db.Query(query, category)
} else {
query := "SELECT dates, timez, categories, amounts, transaction_ids, blockchains, addresses from History"
query := "SELECT dates, timez, categories, amounts, blockchains, addresses from History"
rows, err = db.Query(query)
}
if err != nil {
Expand All @@ -75,12 +75,12 @@ func (h MyBudgetDB) ViewHistory(category string) ([2]interface{}, error) {
defer rows.Close()

for rows.Next() {
if err := rows.Scan(&hv.Date, &hv.Time, &hv.Category, &hv.Amount, &hv.TransactionID, &hv.Blockchain, &hv.Address); err != nil {
if err := rows.Scan(&hv.Date, &hv.Time, &hv.Category, &hv.Amount, &hv.Blockchain, &hv.RecipientAddress); err != nil {
return [2]interface{}{}, err
}

if len(hv.Category) != 0 && hv.Amount != 0 {
tw.AppendRow([]interface{}{hv.Date, hv.Time, hv.Category, hv.Amount, hv.TransactionID, hv.Blockchain, hv.Address})
tw.AppendRow([]interface{}{hv.Date, hv.Time, hv.Category, hv.Amount, hv.Blockchain, hv.RecipientAddress})
}
}

Expand Down
1 change: 0 additions & 1 deletion framework/db/migrations/001_create_budget_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ CREATE TABLE IF NOT EXISTS History (
timez VARCHAR(255) NOT NULL,
categories VARCHAR(255) NOT NULL,
amounts INT NOT NULL,
transaction_ids VARCHAR(255) NOT NULL,
blockchains VARCHAR(255) NOT NULL,
addresses VARCHAR(255) NOT NULL
);
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/superoo7/go-gecko v1.0.0 // indirect
github.com/supranational/blst v0.3.11 // indirect
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20190404155422-f8f10df84213/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU=
Expand Down Expand Up @@ -66,6 +68,7 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY=
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU=
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
Expand Down Expand Up @@ -116,6 +119,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/superoo7/go-gecko v1.0.0 h1:Xa1hZu2AYSA20eVMEd4etY0fcJoEI5deja1mdRmqlpI=
github.com/superoo7/go-gecko v1.0.0/go.mod h1:6AMYHL2wP2EN8AB9msPM76Lbo8L/MQOknYjvak5coaY=
github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4=
github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
Expand All @@ -130,6 +135,7 @@ go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
golang.org/x/arch v0.0.0-20190312162104-788fe5ffcd8c/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
Expand Down Expand Up @@ -157,10 +163,12 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/h2non/gock.v1 v1.0.14/go.mod h1:sX4zAkdYX1TRGJ2JY156cFspQn4yRWn6p9EMdODlynE=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU=
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
4 changes: 2 additions & 2 deletions interfaces/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ type SpendAmount interface {
UpdateBudgetAndTotalAmount(sv *entities.SpendingVariables) error
HandleExceededBudget(sv *entities.SpendingVariables) error
ValidBudgetValues(sv *entities.SpendingVariables) error
SpendMoney(category string, spending_amount int) error
StoreHistory(category string, spending_amount int) error
SpendMoney(category, recipient_address string, spending_amount int) error
StoreHistory(category, recipientAddress string, spending_amount int) error

HourlyNotification(category string)
DailyNotification(hour, min int, category string)
Expand Down
15 changes: 7 additions & 8 deletions usecases/app/spend/history.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,17 @@ import (
"github.com/ibilalkayy/flow/entities"
)

func (h MySpending) StoreHistory(category string, spending_amount int) error {
func (h MySpending) StoreHistory(category, recipientAddress string, spending_amount int) error {
currentDate := time.Now().Format("2006-01-02")
currentTime := time.Now().Format("03:04:05 PM")

hv := entities.HistoryVariables{
Date: currentDate,
Time: currentTime,
Category: category,
Amount: spending_amount,
TransactionID: "transaction id",
Blockchain: "ethereum",
Address: "ethereum address",
Date: currentDate,
Time: currentTime,
Category: category,
Amount: spending_amount,
Blockchain: "ethereum",
RecipientAddress: recipientAddress,
}

err := h.Deps.ManageBudget.InsertHistory(&hv)
Expand Down
8 changes: 6 additions & 2 deletions usecases/app/spend/spend.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import (
"fmt"

"github.com/ibilalkayy/flow/entities"
"github.com/ibilalkayy/flow/framework/blockchain"
"github.com/ibilalkayy/flow/handler"
)

type MySpending struct {
*handler.Handler
}

func (h MySpending) SpendMoney(category string, spending_amount int) error {
func (h MySpending) SpendMoney(category, recipient_address string, spending_amount int) error {
values, err := h.Deps.ManageBudget.ViewBudget(category)
if err != nil {
return err
Expand Down Expand Up @@ -48,6 +49,7 @@ func (h MySpending) SpendMoney(category string, spending_amount int) error {
IncludedCatogeries: included_categories_in_total_amount,
TotalAmount: total_amount,
SpendingAmount: spending_amount,
RecipientAddress: recipient_address,
TotalAmountSpent: total_amount_spent,
BudgetCategoryAmount: budget_category_amount,
BudgetCategorySpentAmount: budget_category_spent_amount,
Expand All @@ -59,6 +61,8 @@ func (h MySpending) SpendMoney(category string, spending_amount int) error {
return err
}

blockchain.SpendFunds(float64(sv.SpendingAmount), sv.RecipientAddress)

return nil
}

Expand Down Expand Up @@ -131,7 +135,7 @@ func (h MySpending) UpdateBudgetAndTotalAmount(sv *entities.SpendingVariables) e
return err
}

err = h.Deps.SpendAmount.StoreHistory(sv.Category, sv.SpendingAmount)
err = h.Deps.SpendAmount.StoreHistory(sv.Category, sv.RecipientAddress, sv.SpendingAmount)
if err != nil {
return err
}
Expand Down

0 comments on commit 95a994a

Please sign in to comment.