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

Custom registration #457

Merged
merged 10 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
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
69 changes: 69 additions & 0 deletions chain.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package core

import (
"fmt"

"github.com/iden3/go-iden3-core/v2/w3c"
)

// ChainID is alias for int32 that represents ChainID
type ChainID int32

// ChainIDs Object containing chain IDs for various blockchains and networks.
var chainIDs = map[string]ChainID{
"eth:main": 1,
"eth:goerli": 5,
"eth:sepolia": 11155111,
"polygon:main": 137,
"polygon:mumbai": 80001,
"zkevm:main": 1101,
"zkevm:test": 1442,
}

// ChainIDfromDID returns chain name from w3c.DID
func ChainIDfromDID(did w3c.DID) (ChainID, error) {

id, err := IDFromDID(did)
if err != nil {
return 0, err
}

blockchain, err := BlockchainFromID(id)
if err != nil {
return 0, err
}

networkID, err := NetworkIDFromID(id)
if err != nil {
return 0, err
}

chainID, ok := chainIDs[fmt.Sprintf("%s:%s", blockchain, networkID)]
if !ok {
return 0, fmt.Errorf("chainID not found for %s:%s", blockchain, networkID)
}

return chainID, nil
}

// RegisterChainID registers chainID for blockchain and network
func RegisterChainID(blockchain Blockchain, network NetworkID, chainID int) error {

k := fmt.Sprintf("%s:%s", blockchain, network)
if existingChainID, ok := chainIDs[k]; ok && existingChainID != ChainID(chainID) {
vmidyllic marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("chainID %s:%s already registered", blockchain, network)
}
chainIDs[k] = ChainID(chainID)

return nil
}

// GetChainID returns chainID for blockchain and network
func GetChainID(blockchain Blockchain, network NetworkID) (ChainID, error) {
k := fmt.Sprintf("%s:%s", blockchain, network)
if _, ok := chainIDs[k]; !ok {
return 0, fmt.Errorf("chainID not registered for %s:%s", blockchain, network)
}

return chainIDs[k], nil
}
176 changes: 170 additions & 6 deletions did.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,22 @@ const (
DIDMethodOther DIDMethod = ""
)

var didMethods = map[DIDMethod]DIDMethod{
DIDMethodIden3: DIDMethodIden3,
DIDMethodPolygonID: DIDMethodPolygonID,
DIDMethodOther: DIDMethodOther,
}

// GetDIDMethod returns DID method by name
func GetDIDMethod(name string) (DIDMethod, error) {

method, ok := didMethods[DIDMethod(name)]
if !ok {
return DIDMethodOther, fmt.Errorf("DID method '%s' not found", name)
}
return method, nil
}

// Blockchain id of the network "eth", "polygon", etc.
type Blockchain string

Expand All @@ -56,37 +72,100 @@ const (
NoChain Blockchain = ""
)

var blockchains = map[Blockchain]Blockchain{
Ethereum: Ethereum,
Polygon: Polygon,
ZkEVM: ZkEVM,
UnknownChain: UnknownChain,
ReadOnly: ReadOnly,
NoChain: NoChain,
}

// GetBlockchain returns blockchain by name
func GetBlockchain(name string) (Blockchain, error) {
blockchain, ok := blockchains[Blockchain(name)]
if !ok {
return UnknownChain, fmt.Errorf("blockchain '%s' not found", name)
}
return blockchain, nil
}

// RegisterBlockchain registers new blockchain
func RegisterBlockchain(b Blockchain) error {
blockchains[b] = b
return nil
}

// NetworkID is method specific network identifier
type NetworkID string

const (
// Main is main network
Main NetworkID = "main"

// Mumbai is polygon mumbai test network
Mumbai NetworkID = "mumbai"

// Goerli is ethereum goerli test network
Goerli NetworkID = "goerli" // goerli
// Sepolia is ethereum Sepolia test network
Sepolia NetworkID = "sepolia"

// Test is test network
Test NetworkID = "test"

// UnknownNetwork is used when it's not possible to retrieve network from identifier
UnknownNetwork NetworkID = "unknown"
// NoNetwork should be used for readonly identity to build readonly flag
NoNetwork NetworkID = ""
)

var networks = map[NetworkID]NetworkID{
Main: Main,
Mumbai: Mumbai,
Goerli: Goerli,
Sepolia: Sepolia,
Test: Test,
UnknownNetwork: UnknownNetwork,
NoNetwork: NoNetwork,
}
OBrezhniev marked this conversation as resolved.
Show resolved Hide resolved

// GetNetwork returns network by name
func GetNetwork(name string) (NetworkID, error) {
network, ok := networks[NetworkID(name)]
if !ok {
return UnknownNetwork, fmt.Errorf("network '%s' not found", name)
}
return network, nil
}

// RegisterNetwork registers new network
func RegisterNetwork(n NetworkID) error {
networks[n] = n
return nil
}

// DIDMethodByte did method flag representation
var DIDMethodByte = map[DIDMethod]byte{
DIDMethodIden3: 0b00000001,
DIDMethodPolygonID: 0b00000010,
DIDMethodOther: 0b11111111,
}

// RegisterDIDMethod registers new DID method with byte flag
func RegisterDIDMethod(m DIDMethod, b byte) error {

if existingByte, ok := DIDMethodByte[m]; ok && existingByte != b {
vmidyllic marked this conversation as resolved.
Show resolved Hide resolved
return fmt.Errorf("DID method %s already registered", m)
}

max := DIDMethodByte[DIDMethodOther]
if b >= max {
return fmt.Errorf("Can't register DID method byte: current %b, maximum byte allowed: %b", b, max-1)
}

didMethods[m] = m
DIDMethodByte[m] = b

return nil
}

// DIDNetworkFlag is a structure to represent DID blockchain and network id
type DIDNetworkFlag struct {
Blockchain Blockchain
Expand Down Expand Up @@ -126,6 +205,88 @@ var DIDMethodNetwork = map[DIDMethod]map[DIDNetworkFlag]byte{
},
}

// DIDMethodNetworkParams is a structure to represent DID method network options
type DIDMethodNetworkParams struct {
Method DIDMethod
Blockchain Blockchain
Network NetworkID
NetworkFlag byte
}

type registrationOptions struct {
chainID *int
methodByte *byte
}

// RegistrationOptions is a type for DID method network options
type RegistrationOptions func(params *registrationOptions)

// WithChainID registers new chain ID method with byte flag
func WithChainID(chainID int) RegistrationOptions {
return func(opts *registrationOptions) {
opts.chainID = &chainID
}
}

// WithDIDMethodByte registers new DID method with byte flag
func WithDIDMethodByte(methodByte byte) RegistrationOptions {
return func(opts *registrationOptions) {
opts.methodByte = &methodByte
}
}

// RegisterDIDMethodNetwork registers new DID method network
func RegisterDIDMethodNetwork(params DIDMethodNetworkParams, opts ...RegistrationOptions) error {
var err error
o := registrationOptions{}
for _, opt := range opts {
opt(&o)
}

b := params.Blockchain
n := params.Network
m := params.Method

err = RegisterBlockchain(b)
if err != nil {
return err
}

err = RegisterNetwork(n)
if err != nil {
return err
}

if o.methodByte != nil {
err = RegisterDIDMethod(m, *o.methodByte)
if err != nil {
return err
}
}

flg := DIDNetworkFlag{Blockchain: b, NetworkID: n}

if _, ok := DIDMethodNetwork[m]; !ok {
DIDMethodNetwork[m] = map[DIDNetworkFlag]byte{}
}

if o.chainID != nil {
err = RegisterChainID(b, n, *o.chainID)
if err != nil {
return err
}
}

if existed, ok := DIDMethodNetwork[m][flg]; ok && existed != params.NetworkFlag {
return fmt.Errorf("DID method network '%s' with blockchain '%s' and network '%s' already registered",
m, b, n)
}

DIDMethodNetwork[m][flg] = params.NetworkFlag
return nil

}

// BuildDIDType builds bytes type from chain and network
func BuildDIDType(method DIDMethod, blockchain Blockchain,
network NetworkID) ([2]byte, error) {
Expand Down Expand Up @@ -218,8 +379,11 @@ func newIDFromUnsupportedDID(did w3c.DID) ID {
}

func idFromDID(did w3c.DID) (ID, error) {
method := DIDMethod(did.Method)
_, ok := DIDMethodByte[method]
method, ok := didMethods[DIDMethod(did.Method)]
if !ok {
method = DIDMethodOther
}
_, ok = DIDMethodByte[method]
if !ok || method == DIDMethodOther {
return ID{}, ErrMethodUnknown
}
Expand Down
Loading