Skip to content

Commit

Permalink
upload metadata to ipfs;
Browse files Browse the repository at this point in the history
Signed-off-by: tcar <tcar121293@gmail.com>
  • Loading branch information
tcar121293 committed Jul 24, 2024
1 parent 23adb47 commit 8032c0e
Showing 1 changed file with 88 additions and 10 deletions.
98 changes: 88 additions & 10 deletions chains/btc/executor/executor.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package executor

import (
"bytes"
"context"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"

Check failure on line 9 in chains/btc/executor/executor.go

View workflow job for this annotation

GitHub Actions / linter-check

SA1019: "io/ioutil" has been deprecated since Go 1.19: As of Go 1.16, the same functionality is now provided by package io or package os, and those implementations should be preferred in new code. See the specific function documentation for details. (staticcheck)
"math/big"
"strconv"
"mime/multipart"
"net/http"
"os"
"sync"
"time"

Expand Down Expand Up @@ -35,6 +40,8 @@ var (
INPUT_SIZE uint64 = 180
OUTPUT_SIZE uint64 = 34
FEE_ROUNDING_FACTOR uint64 = 5
IPFS_JWT_TOKEN string = os.Getenv("IPFS_JWT_TOKEN")
IPFS_URL string = os.Getenv("IPFS_URL")
)

type MempoolAPI interface {
Expand All @@ -47,6 +54,10 @@ type PropStorer interface {
PropStatus(source, destination uint8, depositNonce uint64) (store.PropStatus, error)
}

type IPFSResponse struct {
IpfsHash string `json:"IpfsHash"`
}

type Executor struct {
coordinator *tss.Coordinator
host host.Host
Expand Down Expand Up @@ -277,7 +288,9 @@ func (e *Executor) rawTx(proposals []*BtcTransferProposal, resource config.Resou

func (e *Executor) outputs(tx *wire.MsgTx, proposals []*BtcTransferProposal) (uint64, error) {
outputAmount := uint64(0)
for i, prop := range proposals {
var dataToUpload []map[string]interface{}

for _, prop := range proposals {
addr, err := btcutil.DecodeAddress(prop.Data.Recipient, &e.chainCfg)
if err != nil {
return 0, err
Expand All @@ -290,17 +303,36 @@ func (e *Executor) outputs(tx *wire.MsgTx, proposals []*BtcTransferProposal) (ui
txOut := wire.NewTxOut(int64(prop.Data.Amount), destinationAddrByte)
tx.AddTxOut(txOut)

opReturnData := []byte(strconv.Itoa(int(prop.Source)) + "_" + strconv.Itoa(int(prop.Data.DepositNonce)))
opReturnScript, err := txscript.NullDataScript(opReturnData)
if err != nil {
return 0, err
}

opReturnOut := wire.NewTxOut(0, opReturnScript)
tx.AddTxOut(opReturnOut)
dataToUpload = append(dataToUpload, map[string]interface{}{
"sourceDomain": prop.Source,
"depositNonce": prop.Data.DepositNonce,
})

outputAmount += prop.Data.Amount
}

// Convert the array to JSON
jsonData, err := json.Marshal(dataToUpload)
if err != nil {
log.Error().Err(err).Msg("Error occured while handling data for upload")

}

// Upload to IPFS
cid, err := uploadToIpfs(jsonData)
if err != nil {
log.Error().Err(err).Msg("Error occured while uploading metadata to ipfs")
}

// Store the CID in OP_RETURN
opReturnData := []byte("syg_" + cid)
opReturnScript, err := txscript.NullDataScript(opReturnData)
if err != nil {
log.Error().Err(err).Msg("Error occured while constructiong OP_RETURN data")
}

opReturnOut := wire.NewTxOut(0, opReturnScript)
tx.AddTxOut(opReturnOut)
return outputAmount, nil
}

Expand Down Expand Up @@ -417,3 +449,49 @@ func (e *Executor) storeProposalsStatus(props []*BtcTransferProposal, status sto
}
e.propMutex.Unlock()
}

func uploadToIpfs(data []byte) (string, error) {
// url := "https://api.pinata.cloud/pinning/pinFileToIPFS"

// Create a new multipart form file
body := new(bytes.Buffer)
writer := multipart.NewWriter(body)
part, err := writer.CreateFormFile("file", "metadata.json")
if err != nil {
return "", err
}
part.Write(data)

Check failure on line 463 in chains/btc/executor/executor.go

View workflow job for this annotation

GitHub Actions / linter-check

Error return value of `part.Write` is not checked (errcheck)
writer.Close()

// Create a new request
req, err := http.NewRequest("POST", IPFS_URL, body)
if err != nil {
return "", err
}

// Set the headers
req.Header.Add("Authorization", "Bearer "+IPFS_JWT_TOKEN)
req.Header.Add("Content-Type", writer.FormDataContentType())

// Make the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()

// Read the response
respBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}

// Parse the response
var ipfsResponse IPFSResponse
if err := json.Unmarshal(respBody, &ipfsResponse); err != nil {
return "", err
}

return ipfsResponse.IpfsHash, nil
}

0 comments on commit 8032c0e

Please sign in to comment.