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

Add converting base58 to hex #6

Merged
merged 24 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
go/idos-extensions

**/vue/node_modules
**/vue/dist
**/release/
Expand Down Expand Up @@ -41,4 +43,4 @@ dist/*
.run

# go
vendor/
vendor/
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ The IDOS extension requires two configuration variables: `ETH_RPC_URL` and `NEAR
export ETH_RPC_URL=xxx
export NEAR_RPC_URL=xxx
```
By default, `ETH_RPC_URL` is `http://127.0.0.1:8545/`. If you're using macOS and want to connect the chain running in your host machine (i.e. hardhat running locally in development environment), you should use `http://host.docker.internal:8545/` instead to access host machine port from the container.


### Initialization
Expand All @@ -50,7 +51,7 @@ action get_credential ($id) public {
$can_access = grants_eth.has_grants(@caller, $id);
SELECT CASE WHEN $can_access != 1
THEN ERROR('caller does not have access') END;

SELECT content
FROM credentials
WHERE id = $id;
Expand All @@ -69,7 +70,7 @@ interface IKwilWhitelist {
string dataId;
uint256 lockedUntil;
}

function grants_for(address grantee, string dataId)
public view
returns(Grant[] memory)
Expand Down
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ services:
ports:
- 50055:50055
environment:
- ETH_RPC_URL=
- ETH_RPC_URL=http://host.docker.internal:8545/
Copy link
Member

Choose a reason for hiding this comment

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

Again, not a great default. Unsure what to do in this specific case.

- NEAR_RPC_URL=
- PORT=50055
restart: on-failure
Expand Down
12 changes: 12 additions & 0 deletions go/extension/chains/ethereum/ethereum.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package ethereum
import (
"context"
"fmt"
"regexp"

"github.com/idos-network/idos-extensions/extension/chains"
"github.com/idos-network/idos-extensions/extension/chains/ethereum/registry"
Expand Down Expand Up @@ -64,6 +65,17 @@ func (b *Backend) GrantsFor(ctx context.Context, contract, addr, resource string
return grants, nil
}

var publicKeyRegex = regexp.MustCompile("^(:?0x)?[0-9a-fA-F]{130}$")

// Extracted this to be able to test without having to create an RPC connection.
func isValidPublicKey(publicKey string) bool {
return publicKeyRegex.MatchString(publicKey)
}

func (b *Backend) IsValidPublicKey(publicKey string) bool {
return isValidPublicKey(publicKey)
}

type driver struct{}

func (d *driver) New(url string) (chains.ChainBackend, error) {
Expand Down
41 changes: 41 additions & 0 deletions go/extension/chains/ethereum/ethereum_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package ethereum

import (
"testing"
)

func Test_isValidPublicKey(t *testing.T) {
tests := []struct {
publicKey string
want bool
}{
{
"",
false,
},
{
"some random string",
false,
},
{
// Address; not a public key
"0x9E660ba85118b722147BBaf04ED697C95549dF03",
false,
},
{
"0408cf359417716c8c4dd03ab0c3b243b383599cb05c1b276b326c92a8f4b2b4acdcbdd98e9443f8bfc370b40e80f677142dab8cffd348a22fdf4b68ab61c7d78f",
true,
},
{
"0x0408cf359417716c8c4dd03ab0c3b243b383599cb05c1b276b326c92a8f4b2b4acdcbdd98e9443f8bfc370b40e80f677142dab8cffd348a22fdf4b68ab61c7d78f",
true,
},
}
for _, tt := range tests {
t.Run(tt.publicKey, func(t *testing.T) {
if got := isValidPublicKey(tt.publicKey); got != tt.want {
t.Errorf("isValidPublicKey() = %v, want %v", got, tt.want)
}
})
}
}
1 change: 1 addition & 0 deletions go/extension/chains/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type GrantChecker interface {
type ChainBackend interface {
GrantChecker
Height(context.Context) (uint64, error)
IsValidPublicKey(public_key string) bool
// TODO: Close(), for ws connections
}

Expand Down
30 changes: 30 additions & 0 deletions go/extension/chains/near/near.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/eteu-technologies/near-api-go/pkg/client"
"github.com/eteu-technologies/near-api-go/pkg/client/block"
"github.com/idos-network/idos-extensions/extension/chains"
"github.com/mr-tron/base58"
)

// isNearAcct checks if the string is a valid near account name. This is either
Expand Down Expand Up @@ -124,6 +125,35 @@ func (nb *Backend) GrantsFor(ctx context.Context, registry, acct, resource strin
return grants, nil
}

const NEAR_KEY_LENGTH = 32

func isValidPublicKey(publicKey string) (bool, error) {
pieces := strings.SplitN(publicKey, ":", 2)
if len(pieces) != 2 {
return false, fmt.Errorf("unrecognized format for NEAR public key: %s", publicKey)
}
if pieces[0] != "ed25519" {
return false, fmt.Errorf("unsupported NEAR public key type: %s", pieces[0])
}

binaryPayload, err := base58.Decode(pieces[1])
if err != nil {
return false, fmt.Errorf("unable to decode %s: %w", pieces[1], err)
}

binaryPayloadLen := len(binaryPayload)
if binaryPayloadLen != NEAR_KEY_LENGTH {
return false, fmt.Errorf("wrong binary length: was expecting %d, got %d", NEAR_KEY_LENGTH, binaryPayloadLen)
}

return true, nil
}

func (b *Backend) IsValidPublicKey(publicKey string) bool {
result, _ := isValidPublicKey(publicKey)
return result
}

type driver struct{}

func (d *driver) New(url string) (chains.ChainBackend, error) {
Expand Down
50 changes: 0 additions & 50 deletions go/extension/chains/near/near_online_test.go

This file was deleted.

39 changes: 39 additions & 0 deletions go/extension/chains/near/near_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,42 @@ func Test_isNearAcct(t *testing.T) {
})
}
}

func Test_isValidPublicKey(t *testing.T) {
tests := []struct {
publicKey string
want bool
}{
{
"",
false,
},
{
"blah.near",
false,
},
{
"derp:herp",
false,
},
{
"ed25519:INVALID",
false,
},
{
"ed25519:7dLLbzqc6kgGAC6smmJUUh9xqxH9habnLhptauA",
false,
},
{
"ed25519:7dLLbzqc6kgGAC6smmJUUh9xqxH9habnLhptauAymmUJ",
true,
},
}
for _, tt := range tests {
t.Run(tt.publicKey, func(t *testing.T) {
if res, _ := isValidPublicKey(tt.publicKey); res != tt.want {
t.Errorf("isNearAcct() = %v, want %v", res, tt.want)
}
})
}
}
66 changes: 64 additions & 2 deletions go/extension/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@ package extension

import (
"context"
"encoding/hex"
"errors"
"fmt"
"log"
"regexp"

"github.com/idos-network/idos-extensions/extension/chains"

"github.com/kwilteam/kwil-extensions/server"
"github.com/kwilteam/kwil-extensions/types"

"github.com/mr-tron/base58"
)

const (
Expand Down Expand Up @@ -61,8 +65,11 @@ func (e *FractalExt) BuildServer(logger *log.Logger) (*server.ExtensionServer, e
}).
WithMethods(
map[string]server.MethodFunc{
"get_block_height": server.WithOutputsCheck(e.BlockHeight, 1),
"has_grants": server.WithInputsCheck(server.WithOutputsCheck(e.GrantsFor, 1), 2),
"get_block_height": server.WithOutputsCheck(e.BlockHeight, 1),
"has_grants": server.WithInputsCheck(server.WithOutputsCheck(e.GrantsFor, 1), 2),
"implicit_address_to_public_key": server.WithInputsCheck(server.WithOutputsCheck(e.ImplicitAddressToPublicKey, 1), 1),
"determine_wallet_type": server.WithInputsCheck(server.WithOutputsCheck(e.DetermineWalletType, 1), 1),
"is_valid_public_key": server.WithInputsCheck(server.WithOutputsCheck(e.IsValidPublicKey, 1), 1),
}).
Build()
}
Expand Down Expand Up @@ -141,6 +148,61 @@ func (e *FractalExt) GrantsFor(ctx *types.ExecutionContext, values ...*types.Sca
return encodeScalarValues(exist)
}

func (e *FractalExt) ImplicitAddressToPublicKey(ctx *types.ExecutionContext, values ...*types.ScalarValue) ([]*types.ScalarValue, error) {
inputHex, err := values[0].String()
if err != nil {
return nil, fmt.Errorf("convert value to string failed: %w", err)
}
binaryString, _ := hex.DecodeString(inputHex)
pkoch marked this conversation as resolved.
Show resolved Hide resolved
pkoch marked this conversation as resolved.
Show resolved Hide resolved
base58 := base58.Encode(binaryString)
var public_key string
if len(inputHex) != 64 || base58 == "" {
public_key = ""
} else {
public_key = fmt.Sprintf("ed25519:%s", base58)
}

return encodeScalarValues(public_key)
}

func (e *FractalExt) IsValidPublicKey(ctx *types.ExecutionContext, values ...*types.ScalarValue) ([]*types.ScalarValue, error) {
be, _, err := e.chainBackend(ctx)
if err != nil {
return nil, err
}

public_key, err := values[0].String()
if err != nil {
return nil, fmt.Errorf("convert value to string failed: %w", err)
}

var result uint
if be.IsValidPublicKey(public_key) {
result = 1
} else {
result = 0
}
return encodeScalarValues(result)
}

// This has very dumb logic: eth address returns EVM type, and NEAR returns otherwise.
// TODO: make the logic more detailed and return error is the address is neither EVM no NEAR.
func (e *FractalExt) DetermineWalletType(ctx *types.ExecutionContext, values ...*types.ScalarValue) ([]*types.ScalarValue, error) {
address, err := values[0].String()
if err != nil {
return nil, fmt.Errorf("convert value to string failed: %w", err)
}
re := regexp.MustCompile("^0x[0-9a-fA-F]{40}$")
pkoch marked this conversation as resolved.
Show resolved Hide resolved
var wallet_type string
if re.MatchString(address) {
wallet_type = "EVM"
} else {
wallet_type = "NEAR"
pkoch marked this conversation as resolved.
Show resolved Hide resolved
}

return encodeScalarValues(wallet_type)
}

// initialize checks that the meta data includes all required fields and applies
// any default values.
func initialize(ctx context.Context, metadata map[string]string) (map[string]string, error) {
Expand Down
10 changes: 5 additions & 5 deletions go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/eteu-technologies/near-api-go v0.0.2-0.20221130095932-ef78f2789388
github.com/ethereum/go-ethereum v1.12.0
github.com/kwilteam/kwil-extensions v0.0.0-20230727040522-1cfd930226b7
github.com/mr-tron/base58 v1.2.0
)

require (
Expand All @@ -25,18 +26,17 @@ require (
github.com/gorilla/websocket v1.4.2 // indirect
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.5 // indirect
github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/tklauser/go-sysconf v0.3.5 // indirect
github.com/tklauser/numcpus v0.2.2 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230710151506-e685fd7b542b // indirect
google.golang.org/grpc v1.56.2 // indirect
google.golang.org/grpc v1.56.3 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect
)
Loading