Skip to content

Commit

Permalink
Merge pull request #6 from fuseio/feat/check-delegation
Browse files Browse the repository at this point in the history
chor: update table structure
  • Loading branch information
Supeeerpower authored Jan 25, 2025
2 parents af39280 + 8d2d54a commit 5772fd5
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 37 deletions.
33 changes: 22 additions & 11 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,25 @@ import (
_ "github.com/mattn/go-sqlite3"
)

type OwnershipStatus int

const (
NoNFT OwnershipStatus = iota // 0
OwnsNFT // 1
HasDelegation // 2
)

type Database struct {
db *sql.DB
logger *log.Logger
}

// Add this struct after the Database struct
type ClientInfo struct {
Address string `json:"address"`
TokenID string `json:"token_id"`
CreatedAt time.Time `json:"created_at"`
Address string `json:"address"`
TokenID string `json:"token_id"`
OwnershipStatus OwnershipStatus `json:"ownership_status"`
CreatedAt time.Time `json:"created_at"`
}

func NewDatabase(dbPath string, logger *log.Logger) (*Database, error) {
Expand Down Expand Up @@ -48,11 +57,11 @@ func NewDatabase(dbPath string, logger *log.Logger) (*Database, error) {
}

func initializeTables(db *sql.DB) error {
// Add your table creation statements here
createTableSQL := `
CREATE TABLE IF NOT EXISTS clients (
address TEXT PRIMARY KEY,
token_id TEXT NOT NULL,
ownership_status INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);`

Expand All @@ -64,12 +73,14 @@ func (d *Database) Close() error {
return d.db.Close()
}

func (d *Database) RegisterClient(address, tokenID string) error {
func (d *Database) RegisterClient(address, tokenID string, status OwnershipStatus) error {
_, err := d.db.Exec(`
INSERT INTO clients (address, token_id)
VALUES (?, ?)
ON CONFLICT(address) DO UPDATE SET token_id = excluded.token_id
`, address, tokenID)
INSERT INTO clients (address, token_id, ownership_status)
VALUES (?, ?, ?)
ON CONFLICT(address) DO UPDATE SET
token_id = excluded.token_id,
ownership_status = excluded.ownership_status
`, address, tokenID, status)

if err != nil {
d.logger.Printf("Error registering client: %v", err)
Expand Down Expand Up @@ -104,7 +115,7 @@ func (d *Database) GetClientTokenID(address string) (string, error) {
// Add this new function at the end of the file
func (d *Database) GetAllClients() ([]ClientInfo, error) {
rows, err := d.db.Query(`
SELECT address, token_id, created_at
SELECT address, token_id, ownership_status, created_at
FROM clients
ORDER BY created_at DESC
`)
Expand All @@ -117,7 +128,7 @@ func (d *Database) GetAllClients() ([]ClientInfo, error) {
var clients []ClientInfo
for rows.Next() {
var client ClientInfo
err := rows.Scan(&client.Address, &client.TokenID, &client.CreatedAt)
err := rows.Scan(&client.Address, &client.TokenID, &client.OwnershipStatus, &client.CreatedAt)
if err != nil {
d.logger.Printf("Error scanning client row: %v", err)
return nil, err
Expand Down
4 changes: 3 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ services:
- RPC_URL=https://rpc.fuse.io
- NFT_CONTRACT_ADDRESS=0x9Dbe0138C9b547c9467b5a4Ca6b566D1F6A8B997
- DELEGATE_CONTRACT_ADDRESS=0xf8820d0bB4714aCc91aF7db8c67a967CA5fF3f74
# Add any other environment variables your application needs
# Add this to remove the database file before starting
# command: >
# sh -c "rm -f /data/data.db* && ./server"
restart: unless-stopped

volumes:
Expand Down
40 changes: 15 additions & 25 deletions handlers/checknft.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,35 +83,25 @@ func CheckNFT(db *database.Database, nftChecker *blockchain.NFTChecker, delegate
return
}

var status database.OwnershipStatus
if hasNFT {
response.Status = "success"
response.Message = "Address owns NFT"
}

// If no direct ownership, check delegations
if !hasNFT {
status = database.OwnsNFT
} else {
checksumAddr := common.HexToAddress(req.Address)
contractAddr := nftChecker.GetContractAddress()

if req.Owner == "" {
response.Status = "error"
response.Message = "Address does not have NFT, and to check delegation status, Owner Address is required"
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(response)
return
}

ownerAddr := common.HexToAddress(req.Owner)

// Check ERC1155 delegation if still no access
if !hasNFT {
rights := common.HexToHash("0x69706c6963656e73650000000000000000000000000000000000000000000000")
amount, err := delegateRegistry.CheckDelegateForERC1155(checksumAddr, ownerAddr, contractAddr, tokenID, rights)
if err == nil && amount != nil && amount.Cmp(big.NewInt(0)) > 0 {
hasNFT = true
response.Status = "success"
response.Message = "Address does not have NFT, but has delegation for required NFT"
}
rights := common.HexToHash("0x69706c6963656e73650000000000000000000000000000000000000000000000")

amount, err := delegateRegistry.CheckDelegateForERC1155(checksumAddr, ownerAddr, contractAddr, tokenID, rights)
if err == nil && amount != nil && amount.Cmp(big.NewInt(0)) > 0 {
hasNFT = true
response.Status = "success"
response.Message = "Address does not have NFT, but has delegation for required NFT"
status = database.HasDelegation
} else {
status = database.NoNFT
}
}

Expand All @@ -124,13 +114,13 @@ func CheckNFT(db *database.Database, nftChecker *blockchain.NFTChecker, delegate
}

if !exists {
if err := db.RegisterClient(req.Address, req.TokenID); err != nil {
if err := db.RegisterClient(req.Address, req.TokenID, status); err != nil {
http.Error(w, "Failed to register client", http.StatusInternalServerError)
return
}
} else {
// Update token ID if client already exists
if err := db.RegisterClient(req.Address, req.TokenID); err != nil {
if err := db.RegisterClient(req.Address, req.TokenID, status); err != nil {
http.Error(w, "Failed to update client token ID", http.StatusInternalServerError)
return
}
Expand Down

0 comments on commit 5772fd5

Please sign in to comment.