Skip to content

Commit

Permalink
create spam control for nft description
Browse files Browse the repository at this point in the history
  • Loading branch information
zakhar-petukhov committed Nov 30, 2023
1 parent ac76695 commit ffd7f2c
Show file tree
Hide file tree
Showing 15 changed files with 632 additions and 373 deletions.
23 changes: 13 additions & 10 deletions api/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3211,7 +3211,7 @@
"type": "string"
},
"verification": {
"$ref": "#/components/schemas/JettonVerificationType"
"$ref": "#/components/schemas/VerificationType"
}
},
"required": [
Expand Down Expand Up @@ -3337,7 +3337,7 @@
"type": "string"
},
"verification": {
"$ref": "#/components/schemas/JettonVerificationType"
"$ref": "#/components/schemas/VerificationType"
}
},
"required": [
Expand Down Expand Up @@ -3463,14 +3463,6 @@
],
"type": "object"
},
"JettonVerificationType": {
"enum": [
"whitelist",
"blacklist",
"none"
],
"type": "string"
},
"Jettons": {
"properties": {
"jettons": {
Expand Down Expand Up @@ -3856,6 +3848,9 @@
"sale": {
"$ref": "#/components/schemas/Sale"
},
"verification": {
"$ref": "#/components/schemas/VerificationType"
},
"verified": {
"example": true,
"type": "boolean"
Expand Down Expand Up @@ -5016,6 +5011,14 @@
],
"type": "object"
},
"VerificationType": {
"enum": [
"whitelist",
"blacklist",
"none"
],
"type": "string"
},
"WalletDNS": {
"properties": {
"address": {
Expand Down
28 changes: 15 additions & 13 deletions api/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,18 @@ paths:
description: Get blockchain block shards
operationId: getBlockchainMasterchainShards
tags:
- Blockchain
- Blockchain
parameters:
- $ref: '#/components/parameters/masterchainSeqno'
responses:
'200':
description: blockchain block shards
content:
application/json:
schema:
$ref: '#/components/schemas/BlockchainBlockShards'
'default':
$ref: '#/components/responses/Error'
'200':
description: blockchain block shards
content:
application/json:
schema:
$ref: '#/components/schemas/BlockchainBlockShards'
'default':
$ref: '#/components/responses/Error'
/v2/blockchain/masterchain/{masterchain_seqno}/config:
get:
description: Get blockchain config from a specific block, if present.
Expand Down Expand Up @@ -2552,7 +2552,7 @@ components:
items:
type: object
required:
- address
- address
properties:
address:
type: string
Expand Down Expand Up @@ -4387,7 +4387,7 @@ components:
type: array
items:
$ref: '#/components/schemas/DomainBid'
JettonVerificationType:
VerificationType:
type: string
enum:
- whitelist
Expand Down Expand Up @@ -4419,7 +4419,7 @@ components:
type: string
example: https://cache.tonapi.io/images/jetton.jpg
verification:
$ref: '#/components/schemas/JettonVerificationType'
$ref: '#/components/schemas/VerificationType'
JettonBalance:
type: object
required:
Expand Down Expand Up @@ -4531,6 +4531,8 @@ components:
verified:
type: boolean
example: true
verification:
$ref: '#/components/schemas/VerificationType'
metadata:
type: object
additionalProperties: true
Expand Down Expand Up @@ -5655,7 +5657,7 @@ components:
metadata:
$ref: '#/components/schemas/JettonMetadata'
verification:
$ref: '#/components/schemas/JettonVerificationType'
$ref: '#/components/schemas/VerificationType'
holders_count:
type: integer
format: int32
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/account_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ func (h *Handler) GetAccountDnsExpiring(ctx context.Context, params oas.GetAccou
if dns.DnsItem != nil {
for _, n := range nfts {
if n.Address == dns.DnsItem.Address {
dei.DNSItem = oas.NewOptNftItem(convertNFT(ctx, n, h.addressBook, h.metaCache))
dei.DNSItem = oas.NewOptNftItem(h.convertNFT(ctx, n, h.addressBook, h.metaCache))
break
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/dns_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ func (h *Handler) GetDnsInfo(ctx context.Context, params oas.GetDnsInfoParams) (
convertedDomainInfo := oas.DomainInfo{
Name: params.DomainName,
}
convertedDomainInfo.Item.SetTo(convertNFT(ctx, nft, h.addressBook, h.metaCache))
convertedDomainInfo.Item.SetTo(h.convertNFT(ctx, nft, h.addressBook, h.metaCache))
if expTime != 0 {
convertedDomainInfo.ExpiringAt.SetTo(expTime)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/api/event_converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (h *Handler) convertRisk(ctx context.Context, risk wallet.Risk, walletAddre
return oas.Risk{}, err
}
for _, item := range items {
nft := convertNFT(ctx, item, h.addressBook, h.metaCache)
nft := h.convertNFT(ctx, item, h.addressBook, h.metaCache)
oasRisk.Nfts = append(oasRisk.Nfts, nft)
}
}
Expand Down Expand Up @@ -479,7 +479,7 @@ func (h *Handler) convertAction(ctx context.Context, viewer *tongo.AccountID, a
var name string
if len(items) == 1 {
// opentonapi doesn't implement GetNFTs() now
nft = convertNFT(ctx, items[0], h.addressBook, h.metaCache)
nft = h.convertNFT(ctx, items[0], h.addressBook, h.metaCache)
if len(nft.Previews) > 0 {
nftImage = nft.Previews[0].URL
}
Expand Down Expand Up @@ -615,7 +615,7 @@ func (h *Handler) convertAction(ctx context.Context, viewer *tongo.AccountID, a
if a.AuctionBid.Nft == nil {
return oas.Action{}, false, fmt.Errorf("nft is nil")
}
nft.SetTo(convertNFT(ctx, *a.AuctionBid.Nft, h.addressBook, h.metaCache))
nft.SetTo(h.convertNFT(ctx, *a.AuctionBid.Nft, h.addressBook, h.metaCache))
action.AuctionBid.SetTo(oas.AuctionBidAction{
Amount: oas.Price{
Value: fmt.Sprintf("%v", a.AuctionBid.Amount),
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/jetton_converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func jettonPreview(master tongo.AccountID, meta NormalizedMetadata) oas.JettonPr
Address: master.ToRaw(),
Name: meta.Name,
Symbol: meta.Symbol,
Verification: oas.JettonVerificationType(meta.Verification),
Verification: oas.VerificationType(meta.Verification),
Decimals: meta.Decimals,
Image: meta.Image,
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/api/jetton_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (h *Handler) GetJettonInfo(ctx context.Context, params oas.GetJettonInfoPar
Mintable: data.Mintable,
TotalSupply: data.TotalSupply.String(),
Metadata: metadata,
Verification: oas.JettonVerificationType(meta.Verification),
Verification: oas.VerificationType(meta.Verification),
HoldersCount: holdersCount[account.ID],
}, nil
}
Expand Down Expand Up @@ -191,7 +191,7 @@ func (h *Handler) GetJettons(ctx context.Context, params oas.GetJettonsParams) (
Mintable: master.Mintable,
TotalSupply: master.TotalSupply.String(),
Metadata: metadata,
Verification: oas.JettonVerificationType(meta.Verification),
Verification: oas.VerificationType(meta.Verification),
HoldersCount: jettonsHolders[master.Address],
}
results = append(results, info)
Expand Down
97 changes: 50 additions & 47 deletions pkg/api/nft_converters.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/tonkeeper/opentonapi/internal/g"
"github.com/tonkeeper/opentonapi/pkg/bath"
imgGenerator "github.com/tonkeeper/opentonapi/pkg/image"
rules "github.com/tonkeeper/scam_backoffice_rules"
"github.com/tonkeeper/tongo"

"github.com/go-faster/jx"
Expand All @@ -17,14 +18,15 @@ import (
"github.com/tonkeeper/opentonapi/pkg/references"
)

func convertNFT(ctx context.Context, item core.NftItem, book addressBook, metaCache metadataCache) oas.NftItem {
func (h *Handler) convertNFT(ctx context.Context, item core.NftItem, book addressBook, metaCache metadataCache) oas.NftItem {
i := oas.NftItem{
Address: item.Address.ToRaw(),
Index: item.Index.BigInt().Int64(),
Owner: convertOptAccountAddress(item.OwnerAddress, book),
Verified: item.Verified,
Metadata: anyToJSONRawMap(item.Metadata),
DNS: g.Opt(item.DNS),
Address: item.Address.ToRaw(),
Index: item.Index.BigInt().Int64(),
Owner: convertOptAccountAddress(item.OwnerAddress, book),
Verified: item.Verified,
Metadata: anyToJSONRawMap(item.Metadata),
Verification: oas.NewOptVerificationType(oas.VerificationTypeNone),
DNS: g.Opt(item.DNS),
}
if item.Sale != nil {
tokenName := "TON"
Expand All @@ -35,18 +37,15 @@ func convertNFT(ctx context.Context, item core.NftItem, book addressBook, metaCa
tokenName = UnknownJettonName
}
}
i.SetSale(oas.OptSale{
Value: oas.Sale{
Address: item.Sale.Contract.ToRaw(),
Market: convertAccountAddress(item.Sale.Marketplace, book),
Owner: convertOptAccountAddress(item.Sale.Seller, book),
Price: oas.Price{
Value: fmt.Sprintf("%v", item.Sale.Price.Amount),
TokenName: tokenName,
},
},
Set: true,
})
i.SetSale(oas.NewOptSale(oas.Sale{
Address: item.Sale.Contract.ToRaw(),
Market: convertAccountAddress(item.Sale.Marketplace, book),
Owner: convertOptAccountAddress(item.Sale.Seller, book),
Price: oas.Price{
Value: fmt.Sprintf("%v", item.Sale.Price.Amount),
TokenName: tokenName,
}},
))
}
var image string
if item.CollectionAddress != nil {
Expand All @@ -55,17 +54,12 @@ func convertNFT(ctx context.Context, item core.NftItem, book addressBook, metaCa
i.ApprovedBy = append(i.ApprovedBy, a)
}
}
cInfo, _ := metaCache.getCollectionMeta(ctx, *item.CollectionAddress)

// TODO: REMOVE, FAST HACK
if strings.Contains(cInfo.Description, "ton-staker.com") {
cInfo.Description = "SCAM"
}

collectionInfo, _ := metaCache.getCollectionMeta(ctx, *item.CollectionAddress)
collectionInfo.Description, _ = h.nftDescriptionSpamControl(collectionInfo.Description, i.ApprovedBy)
i.Collection.SetTo(oas.NftItemCollection{
Address: item.CollectionAddress.ToRaw(),
Name: cInfo.Name,
Description: cInfo.Description,
Name: collectionInfo.Name,
Description: collectionInfo.Description,
})
if *item.CollectionAddress == references.RootDotTon && item.DNS != nil && item.Verified {
image = "https://cache.tonapi.io/dns/preview/" + *item.DNS + ".png"
Expand All @@ -77,11 +71,10 @@ func convertNFT(ctx context.Context, item core.NftItem, book addressBook, metaCa
if imageI, prs := item.Metadata["image"]; prs {
image, _ = imageI.(string)
}
// TODO: REMOVE, FAST HACK
if description, ok := item.Metadata["description"]; ok {
if value, ok := description.(string); ok && strings.Contains(value, "ton-staker.com") {
i.Metadata["description"] = []byte(`"SCAM"`)
}
if value, ok := item.Metadata["description"]; ok {
description, verificationType := h.nftDescriptionSpamControl(value.(string), i.ApprovedBy)
i.Verification = oas.NewOptVerificationType(oas.VerificationType(verificationType))
i.Metadata["description"] = []byte(description)
}
}
if image == "" {
Expand All @@ -97,7 +90,7 @@ func convertNFT(ctx context.Context, item core.NftItem, book addressBook, metaCa
return i
}

func convertNftCollection(collection core.NftCollection, book addressBook) oas.NftCollection {
func (h *Handler) convertNftCollection(collection core.NftCollection, book addressBook) oas.NftCollection {
c := oas.NftCollection{
Address: collection.Address.ToRaw(),
NextItemIndex: int64(collection.NextItemIndex),
Expand All @@ -107,32 +100,27 @@ func convertNftCollection(collection core.NftCollection, book addressBook) oas.N
if len(collection.Metadata) == 0 {
return c
}
if known, ok := book.GetCollectionInfoByAddress(collection.Address); ok {
for _, a := range known.Approvers {
c.ApprovedBy = append(c.ApprovedBy, a)
}
}
metadata := map[string]jx.Raw{}
image := references.Placeholder
for k, v := range collection.Metadata {
// TODO: REMOVE, FAST HACK
if k == "description" {
if value, ok := v.(string); ok && strings.Contains(value, "ton-staker.com") {
v = "SCAM"
}
v, _ = h.nftDescriptionSpamControl(v.(string), c.ApprovedBy)
}

var err error
if k == "image" {
if i, ok := v.(string); ok && i != "" {
image = i
}
}
metadata[k], err = json.Marshal(v)
if err != nil {
var err error
if metadata[k], err = json.Marshal(v); err != nil {
continue
}
}
if known, ok := book.GetCollectionInfoByAddress(collection.Address); ok {
for _, a := range known.Approvers {
c.ApprovedBy = append(c.ApprovedBy, a)
}
}
c.Metadata.SetTo(metadata)
for _, size := range []int{5, 100, 500, 1500} {
url := imgGenerator.DefaultGenerator.GenerateImageUrl(image, size, size)
Expand Down Expand Up @@ -186,3 +174,18 @@ func (h *Handler) convertNftHistory(ctx context.Context, account tongo.AccountID

return events, int64(lastLT), nil
}

func (h *Handler) nftDescriptionSpamControl(description string, approvedBy oas.NftApprovedBy) (string, VerificationType) {
const scam = "SCAM"
if strings.Contains(description, "ton-staker.com") { // TODO: REMOVE, FAST HACK
return scam, VerificationBlacklist
}
if len(approvedBy) > 0 {
return description, VerificationWhitelist
} else {
if spamAction := rules.CheckAction(h.spamFilter.GetRules(), description); spamAction == rules.Drop {
return scam, VerificationBlacklist
}
}
return description, VerificationNone
}
Loading

0 comments on commit ffd7f2c

Please sign in to comment.