Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(webhook): add webhook #2538

Merged
merged 38 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6074411
add models and endpoint, lacking logic
shampoobera Apr 29, 2024
31aab47
just stuff
shampoobera Apr 29, 2024
b5e989a
just stuff
shampoobera Apr 29, 2024
715a453
made general db interface
shampoobera Apr 29, 2024
e2a6214
cleanup
shampoobera Apr 29, 2024
cd41cbc
trying to test
shampoobera Apr 29, 2024
444428b
trying to test
shampoobera Apr 29, 2024
18c0d51
trying ot fix test
shampoobera Apr 29, 2024
799f646
remove interface{} from gorm models, start tests, rework db interface
shampoobera Apr 29, 2024
c22d3c9
add signature
shampoobera Apr 30, 2024
6e0d109
secret
shampoobera Apr 30, 2024
9af0630
look away for now
shampoobera Apr 30, 2024
b5a29e1
finish db test
shampoobera Apr 30, 2024
496d67a
finish tests
golangisfun123 Apr 30, 2024
df7ffc6
add auth
golangisfun123 Apr 30, 2024
0b7b3e9
remove debugging log
golangisfun123 Apr 30, 2024
8b8297a
comments and nits
golangisfun123 Apr 30, 2024
f8a833b
lint
golangisfun123 Apr 30, 2024
d4ac8d6
appsecret and appid
golangisfun123 May 1, 2024
01f8b57
resolve comments
golangisfun123 May 1, 2024
7f81c14
swagger, lint
golangisfun123 May 1, 2024
1c55e8b
feat(synapse-interface): maintenance aggregator using PAUSED_CHAINS (…
bigboydiamonds Apr 30, 2024
a5a3120
Publish
bigboydiamonds Apr 30, 2024
a7e239e
Exempt gh pages (#2541)
trajan0x May 1, 2024
7d2117a
Deploy: `FastBridge` to Scroll (#2525)
ChiTimesChi May 1, 2024
4c7538c
Publish
ChiTimesChi May 1, 2024
6fec3a5
fix: update `forge-std` to 1.8.1, remove `ds-test`, use `solhint` for…
ChiTimesChi May 1, 2024
200eb8b
Publish
ChiTimesChi May 1, 2024
5dc99e4
chore: remove submodules from `contracts-rfq` (#2547)
ChiTimesChi May 1, 2024
1a3000a
Publish
ChiTimesChi May 1, 2024
b40e602
gogenerate
golangisfun123 May 1, 2024
f241759
Revert "gogenerate"
golangisfun123 May 1, 2024
d9e99a0
im dumb
golangisfun123 May 1, 2024
d7963fa
generate
golangisfun123 May 1, 2024
652b099
tidy
golangisfun123 May 1, 2024
d390ea0
update swagger doc
golangisfun123 May 1, 2024
8c215e4
[goreleaser]
trajan0x May 1, 2024
498a067
[goreleaser]
golangisfun123 May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,21 @@
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"eslint.workingDirectories": [
{ "directory": "packages/contracts", "changeProcessCWD": true }
{
"directory": "packages/contracts",
"changeProcessCWD": true
}
],
"eslint.nodePath": "./node_modules/eslint/bin/",
"eslint.format.enable": true,
"editorconfig.generateAuto": false,
"files.trimTrailingWhitespace": true,
"solidity.packageDefaultDependenciesContractsDirectory": "contracts",
"solidity.packageDefaultDependenciesDirectory": "lib",
"solidity.compileUsingRemoteVersion": "v0.8.17",
"solidity.formatter": "prettier"
}
"solidity.compileUsingRemoteVersion": "v0.8.17+commit.8df45f5f",
"solidity.formatter": "prettier",
"solidity.defaultCompiler": "remote"
}
94 changes: 94 additions & 0 deletions contrib/screener-api/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,28 @@

import (
"context"
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"strings"
"time"

"github.com/dubonzi/otelresty"
"github.com/go-resty/resty/v2"
"github.com/google/uuid"
"github.com/synapsecns/sanguine/core/ginhelper"
"github.com/synapsecns/sanguine/core/metrics"
)

var (
BlacklistEndpoint = "/api/data/sync/"

Check failure on line 21 in contrib/screener-api/client/client.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

exported var `BlacklistEndpoint` should have comment or be unexported (golint)
)

// ScreenerClient is an interface for the Screener API.
type ScreenerClient interface {
ScreenAddress(ctx context.Context, ruleset, address string) (blocked bool, err error)
BlacklistAddress(ctx context.Context, body BlackListBody) (string, error)
}

type clientImpl struct {
Expand Down Expand Up @@ -54,6 +65,58 @@
return blockedRes.Blocked, nil
}

type BlackListBody struct {
TypeReq string `json:"typereq"`
Id string `json:"id"`
Data string `json:"data"`
Address string `json:"address"`
Network string `json:"network"`
Tag string `json:"tag"`
Remark string `json:"remark"`
}

type blacklistResponse struct {
Status string `json:"status"`
Error string `json:"error"`
}

func (c clientImpl) BlacklistAddress(ctx context.Context, body BlackListBody) (string, error) {
var blacklistRes blacklistResponse

// TODO: remove, just for testing purposes
// future, take it from some .env or something
appsecret := "appsecret"
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
appid := "appid"

nonce := strings.Replace(uuid.New().String(), "-", "", -1)[:32]

Check failure on line 91 in contrib/screener-api/client/client.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

wrapperFunc: use strings.ReplaceAll method in `strings.Replace(uuid.New().String(), "-", "", -1)` (gocritic)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
timestamp := fmt.Sprintf("%d", time.Now().Unix())
queryString := "" // there is no query string in this post request, ask about this

signature := GenerateSignature(appsecret, appid, timestamp, nonce, queryString, body)

resp, err := c.rClient.R().
SetContext(ctx).
SetHeader("Content-Type", "application/json").
SetHeader("appid", appid).
SetHeader("timestamp", timestamp).
SetHeader("nonce", nonce).
SetHeader("queryString", queryString).
SetHeader("signature", signature).
SetResult(&blacklistRes).
SetBody(body).
Post(BlacklistEndpoint)

if err != nil {
return resp.Status(), fmt.Errorf("error from server: %s: %w", resp.String(), err)
}

if resp.IsError() {
return resp.Status(), fmt.Errorf("error from server: %s", resp.String())
}

return blacklistRes.Status, nil
}

// NewNoOpClient creates a new no-op client for the Screener API.
// it returns false for every address.
func NewNoOpClient() (ScreenerClient, error) {
Expand All @@ -66,4 +129,35 @@
return false, nil
}

func (n noOpClient) BlacklistAddress(_ context.Context, _ BlackListBody) (string, error) {
return "", nil
}

func GenerateSignature(secret string,
appid string,
timestamp string,
nonce string,
queryString string,
body BlackListBody,
) string {
key := []byte(secret)

// concatenate the body
message := fmt.Sprintf(
"%s%s%s%s%s%s%s",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

poor use of %s, just create a concat(...string) method that does this

appid,
timestamp,
nonce,
"POST",
BlacklistEndpoint,
queryString,
body,
)
h := hmac.New(sha256.New, key)
// hash it
h.Write([]byte(message))

return strings.ToLower(hex.EncodeToString(h.Sum(nil)))
}

var _ ScreenerClient = noOpClient{}
25 changes: 24 additions & 1 deletion contrib/screener-api/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,27 @@
import (
"context"
"errors"
"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs"
"time"

"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs"
)

// TODO: make a general db interface.

Check failure on line 12 in contrib/screener-api/db/db.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

comment on exported type BlacklistedAddressWriterDB should be of the form "BlacklistedAddressWriterDB ..." (with optional leading article) (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
type BlacklistedAddressWriterDB interface {
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
PutBlacklistedAddress(ctx context.Context, body BlacklistedAddress) error
DeleteBlacklistedAddress(ctx context.Context, id string) error
UpdateBlacklistedAddress(ctx context.Context, id string, body BlacklistedAddress) error
}

type BlacklistedAddressReaderDB interface {

Check failure on line 19 in contrib/screener-api/db/db.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

exported type `BlacklistedAddressReaderDB` should have comment or be unexported (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
GetBlacklistedAddress(ctx context.Context, address string) (*BlacklistedAddress, error)
}

type BlacklistedAddressDB interface {

Check failure on line 23 in contrib/screener-api/db/db.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

exported type `BlacklistedAddressDB` should have comment or be unexported (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
BlacklistedAddressWriterDB
BlacklistedAddressReaderDB
}

// RuleWriterDB is the interface for writing rules to the database.
type RuleWriterDB interface {
PutAddressIndicators(ctx context.Context, address string, riskIndicator []trmlabs.AddressRiskIndicator) error
Expand All @@ -24,5 +41,11 @@
RuleReaderDB
}

// DB is the general database interface for the screener-api

Check failure on line 44 in contrib/screener-api/db/db.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

Comment should end in a period (godot)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
type DB interface {
BlacklistedAddressDB
RuleDB
}

// ErrNoAddressNotCached is returned when an address is not cached.
var ErrNoAddressNotCached = errors.New("address not cached")
59 changes: 55 additions & 4 deletions contrib/screener-api/db/db_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package db_test

import (
"time"

"github.com/brianvoe/gofakeit/v6"
"github.com/synapsecns/sanguine/contrib/screener-api/db"
"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs"
"time"
"gorm.io/gorm"
)

func (d *DBSuite) TestEmpty() {
d.RunOnAllDBs(func(testDB db.RuleDB) {
d.RunOnAllDBs(func(testDB db.DB) {
testAddress := gofakeit.BitcoinAddress()

// 5 mins ago
Expand All @@ -28,8 +30,8 @@ func (d *DBSuite) TestEmpty() {
})
}

func (d *DBSuite) TestAdressUpdate() {
d.RunOnAllDBs(func(testDB db.RuleDB) {
func (d *DBSuite) TestAddressUpdate() {
d.RunOnAllDBs(func(testDB db.DB) {
testAddress := gofakeit.BitcoinAddress()

// 5 mins ago
Expand Down Expand Up @@ -64,3 +66,52 @@ func (d *DBSuite) TestAdressUpdate() {
d.Require().Error(err, db.ErrNoAddressNotCached)
})
}

func (d *DBSuite) TestBlacklist() {
d.RunOnAllDBs(func(testDB db.DB) {

testAddress := gofakeit.BitcoinAddress()

blacklistBody := db.BlacklistedAddress{
TypeReq: "create",
Id: "testId",
Address: testAddress,
Network: "bitcoin",
Tag: "testTag",
Remark: "testRemark",
}

// blacklist the address
err := testDB.PutBlacklistedAddress(d.GetTestContext(), blacklistBody)
d.Require().NoError(err)
blacklistedAddress, err := testDB.GetBlacklistedAddress(d.GetTestContext(), blacklistBody.Address)
d.Require().NoError(err)
d.Require().NotNil(blacklistedAddress)

// update the address
blacklistBody.TypeReq = "update"
blacklistBody.Remark = "testRemarkUpdated"
err = testDB.UpdateBlacklistedAddress(d.GetTestContext(), blacklistBody.Id, blacklistBody)
d.Require().NoError(err)

// check to make sure it updated
blacklistedAddress, err = testDB.GetBlacklistedAddress(d.GetTestContext(), blacklistBody.Address)
d.Require().NoError(err)
d.Require().NotNil(blacklistedAddress)
d.Require().Equal("testRemarkUpdated", blacklistedAddress.Remark)

// check for non blacklisted address
res, err := testDB.GetBlacklistedAddress(d.GetTestContext(), gofakeit.BitcoinAddress())
d.Require().EqualError(err, gorm.ErrRecordNotFound.Error())
d.Require().Nil(res)

// delete it
err = testDB.DeleteBlacklistedAddress(d.GetTestContext(), blacklistBody.Id)
d.Require().NoError(err)

// delete nonexistent
err = testDB.DeleteBlacklistedAddress(d.GetTestContext(), "NonexistentId")
d.Require().NoError(err)

})
}
57 changes: 55 additions & 2 deletions contrib/screener-api/db/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,61 @@
"encoding/json"
"errors"
"fmt"
"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs"
"gorm.io/gorm/schema"
"strings"
"time"

"github.com/synapsecns/sanguine/contrib/screener-api/trmlabs"
"gorm.io/gorm/schema"
)

// BlacklistedAddress is a blacklisted address.
type BlacklistedAddress struct {
CreatedAt time.Time
UpdatedAt time.Time

TypeReq string `gorm:"column:typereq"`
Id string `gorm:"column:id;primary_key"`

Check failure on line 24 in contrib/screener-api/db/models.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

struct field `Id` should be `ID` (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
Data string `gorm:"column:data"`
Address string `gorm:"column:address"`
Network string `gorm:"column:network"`
Tag string `gorm:"column:tag"`
Remark string `gorm:"column:remark"`
}

func (b BlacklistedAddress) GormDataType() string {

Check failure on line 32 in contrib/screener-api/db/models.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

exported method `BlacklistedAddress.GormDataType` should have comment or be unexported (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
return "json"

Check warning on line 33 in contrib/screener-api/db/models.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/db/models.go#L32-L33

Added lines #L32 - L33 were not covered by tests
}
trajan0x marked this conversation as resolved.
Show resolved Hide resolved

func (b BlacklistedAddress) Value() (driver.Value, error) {

Check failure on line 36 in contrib/screener-api/db/models.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

exported method `BlacklistedAddress.Value` should have comment or be unexported (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
if b == (BlacklistedAddress{}) {
return nil, nil
}
ba, err := json.Marshal(b)
return string(ba), err

Check warning on line 41 in contrib/screener-api/db/models.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/db/models.go#L36-L41

Added lines #L36 - L41 were not covered by tests
}
trajan0x marked this conversation as resolved.
Show resolved Hide resolved

func (b *BlacklistedAddress) Scan(val interface{}) error {

Check failure on line 44 in contrib/screener-api/db/models.go

View workflow job for this annotation

GitHub Actions / Lint (contrib/screener-api)

exported method `BlacklistedAddress.Scan` should have comment or be unexported (golint)
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
if val == nil {
*b = BlacklistedAddress{}
return nil
}
var ba []byte
switch v := val.(type) {
case []byte:
ba = v
case string:
ba = []byte(v)
default:
return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", val))

Check warning on line 56 in contrib/screener-api/db/models.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/db/models.go#L44-L56

Added lines #L44 - L56 were not covered by tests
}
rd := bytes.NewReader(ba)
decoder := json.NewDecoder(rd)
decoder.UseNumber()
err := decoder.Decode(b)
//nolint: wrapcheck
return err

Check warning on line 63 in contrib/screener-api/db/models.go

View check run for this annotation

Codecov / codecov/patch

contrib/screener-api/db/models.go#L58-L63

Added lines #L58 - L63 were not covered by tests
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tip

Codebase Verification

The verification process has confirmed that there is no unit test specifically targeting the Scan method of the BlacklistedAddress struct in the contrib/screener-api/db/models.go file. The search results included various usages of the Scan method across different contexts, but none that directly test the Scan method within the BlacklistedAddress struct.

  • The method is critical for data deserialization and should be thoroughly tested to ensure its correct implementation.
Analysis chain

Ensure Scan method is covered by unit tests.

The Scan method is critical for data deserialization, and it is important to ensure its correct implementation through testing.


The output from the executed script does not confirm the presence of unit tests for the Scan method in the BlacklistedAddress struct. The results show tests for different contexts, which are not relevant to the BlacklistedAddress. To ensure thorough verification, I will refine the search to focus specifically on the BlacklistedAddress struct.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Description: Verify that the `Scan` method in the `BlacklistedAddress` struct is covered by unit tests.

# Find test files for the `models.go` and check for test coverage on the `Scan` method.
rg --files-with-matches --type go $'func Test.*Scan' | xargs rg 'Scan\('

Length of output: 406



Script:

#!/bin/bash
# Description: More specifically verify that the `Scan` method in the `BlacklistedAddress` struct is covered by unit tests.

# Find test files specifically related to the `BlacklistedAddress` struct and check for test coverage on the `Scan` method.
rg --files-with-matches --type go $'func Test.*BlacklistedAddress.*Scan' | xargs rg 'Scan\('

Length of output: 5016


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a descriptive comment for the AddressIndicators struct.

+ // AddressIndicators represents the risk indicators associated with an address.

It's a good practice to provide comments for exported types to improve code readability and maintainability.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// AddressIndicators represents the risk indicators associated with an address.

Add a descriptive comment for the addressRiskIndicators type.

+ // addressRiskIndicators defines a list of risk indicators for an address.

This comment will help other developers understand the purpose of this type at a glance.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// addressRiskIndicators defines a list of risk indicators for an address.

Add a descriptive comment for the ToTRMLabs method.

+ // ToTRMLabs converts address risk indicators to a format used by TRMLabs.

Adding a descriptive comment for this exported method will enhance code readability and maintainability.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// ToTRMLabs converts address risk indicators to a format used by TRMLabs.

Add a descriptive comment for the MakeRecord function.

+ // MakeRecord creates a new AddressIndicators record with the specified address and risk indicators.

Documenting public functions helps other developers understand their purpose and usage quickly.


Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
// MakeRecord creates a new AddressIndicators record with the specified address and risk indicators.

// AddressIndicators is the address indicators for a given address.
type AddressIndicators struct {
CreatedAt time.Time
Expand Down Expand Up @@ -93,3 +142,7 @@
var _ schema.GormDataTypeInterface = addressRiskIndicators{}
var _ driver.Value = addressRiskIndicators{}
var _ sql.Scanner = &addressRiskIndicators{}

var _ schema.GormDataTypeInterface = BlacklistedAddress{}
golangisfun123 marked this conversation as resolved.
Show resolved Hide resolved
var _ driver.Value = BlacklistedAddress{}
var _ sql.Scanner = &BlacklistedAddress{}
Loading
Loading