Skip to content

Commit

Permalink
Merge pull request #3 from PerminovEugene/add-mint-page
Browse files Browse the repository at this point in the history
Add mint page
  • Loading branch information
PerminovEugene authored Oct 18, 2024
2 parents c3b72e1 + c3f887e commit 28b31a8
Show file tree
Hide file tree
Showing 65 changed files with 2,329 additions and 247 deletions.
19 changes: 19 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Attach to Go in Docker with Air",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "/app/packages/backend",
"port": 40000,
"host": "127.0.0.1",
"apiVersion": 2,
"showLog": true
}
]
}
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"[go]": {
"editor.insertSpaces": true,
"editor.formatOnSave": true,
"editor.defaultFormatter": "golang.go"
}
}
Binary file modified .yarn/install-state.gz
Binary file not shown.
16 changes: 16 additions & 0 deletions Dockerfile.backend
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM golang:1.23

WORKDIR /app

RUN go install github.com/go-delve/delve/cmd/dlv@latest

RUN go install github.com/air-verse/air@latest

COPY packages/backend/go.mod ./packages/backend/
COPY packages/backend/go.sum ./packages/backend/

WORKDIR /app/packages/backend

RUN go mod tidy

EXPOSE 8080 40000
22 changes: 2 additions & 20 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,21 +1,3 @@
MIT License
All Rights Reserved.

Copyright (c) 2024 Perminov Eugene

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
© 2024 Eugene Permniv. Unauthorized copying, modification, distribution, or any action based on this source code is strictly prohibited without prior written permission.
17 changes: 17 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ services:
env_file:
- .env

backend:
build:
context: .
dockerfile: ./Dockerfile.backend
ports:
- "8080:8080"
- "40000:40000"
depends_on:
- deploy-blockchain
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
command: "air"
volumes:
- ./packages/backend:/app/packages/backend

networks:
hardhat-net:
driver: bridge
62 changes: 62 additions & 0 deletions packages/backend/.air.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"

[build]
bin = "dlv"
args_bin = [
"exec",
"./tmp/main",
"--headless",
"--listen=0.0.0.0:40000",
"--api-version=2",
"--accept-multiclient"
]
cmd = "go build -gcflags 'all=-N -l' -o ./tmp/main"
full_bin = "dlv exec ./tmp/main --headless --listen=0.0.0.0:40000 --api-version=2 --accept-multiclient --continue"

delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false

[run]
cmd = "dlv exec ./tmp/main --headless --listen=0.0.0.0:40000 --api-version=2 --accept-multiclient"

[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"

[log]
main_only = false
time = false

[misc]
clean_on_exit = false

[proxy]
app_port = 0
enabled = false
proxy_port = 0

[screen]
clear_on_rebuild = false
keep_scroll = true
1 change: 1 addition & 0 deletions packages/backend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
tmp
35 changes: 35 additions & 0 deletions packages/backend/.vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Connect to server",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "${workspaceFolder}",
"port": 8080,
"host": "127.0.0.1"
},
{
"name": "Attach to Process",
"type": "go",
"request": "attach",
"mode": "local",
"processId": 1
},
{
"name": "Attach to Go in Docker with Air",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "/app/packages/backend",
"port": 40000,
"host": "127.0.0.1",
"apiVersion": 2,
"showLog": true
}
]
}
Binary file added packages/backend/backend
Binary file not shown.
25 changes: 25 additions & 0 deletions packages/backend/clients/pinata/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package pinata

import (
"errors"
"net/http"
"os"
)

func NewPinataClient() (*PinataClient, error) {
jwt := os.Getenv("PINATA_JWT")
apiKey := os.Getenv("PINATA_API_KEY")
secret := os.Getenv("PINATA_API_SECRET")

if jwt == "" || apiKey == "" || secret == "" {
return nil, errors.New("Pinata config is invalid")
}

return &PinataClient{
BaseURL: "https://api.pinata.cloud",
Client: &http.Client{},
Jwt: jwt,
ApiKey: apiKey,
ApiSecret: secret,
}, nil
}
115 changes: 115 additions & 0 deletions packages/backend/clients/pinata/pin_file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package pinata

import (
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
)

func (p *PinataClient) PinFile(file io.Reader, fileName string) (PinataPinFileData, error) {
var pinataResponse PinataPinFileData
pr, pw := io.Pipe()
multipartWriter := multipart.NewWriter(pw)

// Write the multipart form data in a goroutine

go func() {
defer pw.Close()
defer multipartWriter.Close()

// Write the file part
formFile, err := multipartWriter.CreateFormFile("file", fileName)
if err != nil {
pw.CloseWithError(fmt.Errorf("Error creating form file: %w", err))
return
}

_, err = io.Copy(formFile, file)
if err != nil {
pw.CloseWithError(fmt.Errorf("Error copying file data: %w", err))
return
}

addPinataMetaToForm(fileName, pw, multipartWriter)
}()

// Create the HTTP request

req, err := http.NewRequest("POST", p.BaseURL+"/pinning/pinFileToIPFS", pr)
if err != nil {
return pinataResponse, fmt.Errorf("Error creating request: %w", err)
}

req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
req.Header.Set("Authorization", "Bearer "+p.Jwt)

// Send the request

client := p.Client
resp, err := client.Do(req)
if err != nil {
return pinataResponse, fmt.Errorf("Error sending request to Pinata: %w", err)
}
defer resp.Body.Close()

// process response

bodyBytes, _ := io.ReadAll(resp.Body)
if err != nil {
return pinataResponse, fmt.Errorf("Error reading response body: %w", err)
}

if resp.StatusCode < 200 || resp.StatusCode >= 300 {
return pinataResponse, fmt.Errorf("Pinata responded with %d: %s", resp.StatusCode, string(bodyBytes))
}

err = json.Unmarshal(bodyBytes, &pinataResponse)
if err != nil {
fmt.Println("Error decoding Pinata response", err)
return pinataResponse, err
}

return pinataResponse, nil
}

func addPinataMetaToForm(
name string,
pw *io.PipeWriter,
multipartWriter *multipart.Writer,
) {
// Write the metadata part

metadata := map[string]string{
"name": name,
}
metadataJSON, err := json.Marshal(metadata)
if err != nil {
pw.CloseWithError(fmt.Errorf("Error marshaling metadata: %w", err))
return
}

err = multipartWriter.WriteField("pinataMetadata", string(metadataJSON))
if err != nil {
pw.CloseWithError(fmt.Errorf("Error writing metadata field: %w", err))
return
}

// Write the options part

options := map[string]uint{
"cidVersion": 1,
}
optionsJSON, err := json.Marshal(options)
if err != nil {
pw.CloseWithError(fmt.Errorf("Error marshaling options: %w", err))
return
}

err = multipartWriter.WriteField("pinataOptions", string(optionsJSON))
if err != nil {
pw.CloseWithError(fmt.Errorf("Error writing options field: %w", err))
return
}
}
Loading

0 comments on commit 28b31a8

Please sign in to comment.