-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add didMethods config option to register custom DID methods (#52)
- Loading branch information
Showing
16 changed files
with
929 additions
and
169 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
package c_polygonid | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
core "github.com/iden3/go-iden3-core/v2" | ||
"github.com/iden3/go-schema-processor/v2/loaders" | ||
"github.com/piprate/json-gold/ld" | ||
) | ||
|
||
type EnvConfig struct { | ||
DIDMethods []MethodConfig | ||
ChainConfigs PerChainConfig | ||
EthereumURL string // Deprecated: Use ChainConfigs instead | ||
StateContractAddr common.Address // Deprecated: Use ChainConfigs instead | ||
ReverseHashServiceUrl string // Deprecated | ||
IPFSNodeURL string | ||
} | ||
|
||
var globalRegistationLock sync.Mutex | ||
var registeredDIDMethods sync.Map | ||
|
||
// NewEnvConfigFromJSON returns empty config if input json is nil. | ||
func NewEnvConfigFromJSON(in []byte) (EnvConfig, error) { | ||
var cfg EnvConfig | ||
if in == nil { | ||
return cfg, nil | ||
} | ||
|
||
var err error | ||
err = json.Unmarshal(in, &cfg) | ||
if err != nil { | ||
return cfg, fmt.Errorf("unable to parse json config: %w", err) | ||
} | ||
|
||
if len(cfg.DIDMethods) == 0 { | ||
return cfg, nil | ||
} | ||
|
||
err = registerDIDMethods(cfg.DIDMethods) | ||
if err != nil { | ||
return cfg, err | ||
} | ||
|
||
var zeroAddr common.Address | ||
for _, didMethod := range cfg.DIDMethods { | ||
chainIDCfg, ok := cfg.ChainConfigs[didMethod.ChainID] | ||
if !ok { | ||
return cfg, fmt.Errorf("no chain config found for chain ID %v", | ||
didMethod.ChainID) | ||
} | ||
if chainIDCfg.RPCUrl == "" { | ||
return cfg, fmt.Errorf("no RPC URL found for chain ID %v", | ||
didMethod.ChainID) | ||
} | ||
if chainIDCfg.StateContractAddr == zeroAddr { | ||
return cfg, fmt.Errorf( | ||
"no state contract address found for chain ID %v", | ||
didMethod.ChainID) | ||
} | ||
} | ||
|
||
return cfg, err | ||
} | ||
|
||
func registerDIDMethods(methodConfigs []MethodConfig) error { | ||
newMethodConfigs := make([]MethodConfig, 0, len(methodConfigs)) | ||
|
||
for _, methodCfg := range methodConfigs { | ||
if _, ok := registeredDIDMethods.Load(methodCfg.Hash()); !ok { | ||
newMethodConfigs = append(newMethodConfigs, methodCfg) | ||
} | ||
} | ||
|
||
if len(newMethodConfigs) == 0 { | ||
return nil | ||
} | ||
|
||
globalRegistationLock.Lock() | ||
defer globalRegistationLock.Unlock() | ||
|
||
for _, methodCfg := range newMethodConfigs { | ||
chainIDi := chainIDToInt(methodCfg.ChainID) | ||
|
||
params := core.DIDMethodNetworkParams{ | ||
Method: methodCfg.MethodName, | ||
Blockchain: methodCfg.Blockchain, | ||
Network: methodCfg.NetworkID, | ||
NetworkFlag: methodCfg.NetworkFlag, | ||
} | ||
err := core.RegisterDIDMethodNetwork(params, | ||
core.WithChainID(chainIDi), | ||
core.WithDIDMethodByte(methodCfg.MethodByte)) | ||
if err != nil { | ||
return fmt.Errorf( | ||
"can't register DID method %v, blockchain %v, network ID %v, "+ | ||
"network flag: %x, method byte %v, chain ID %v: %w", | ||
methodCfg.MethodName, methodCfg.Blockchain, methodCfg.NetworkID, | ||
methodCfg.NetworkFlag, methodCfg.MethodByte, | ||
methodCfg.ChainID, err) | ||
} | ||
|
||
registeredDIDMethods.Store(methodCfg.Hash(), struct{}{}) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (cfg EnvConfig) documentLoader() ld.DocumentLoader { | ||
var ipfsNode loaders.IPFSClient | ||
if cfg.IPFSNodeURL != "" { | ||
ipfsNode = &ipfsCli{rpcURL: cfg.IPFSNodeURL} | ||
} | ||
|
||
var opts []loaders.DocumentLoaderOption | ||
|
||
cacheEngine, err := newBadgerCacheEngine( | ||
withEmbeddedDocumentBytes( | ||
"https://www.w3.org/2018/credentials/v1", | ||
credentialsV1JsonLDBytes)) | ||
if err == nil { | ||
opts = append(opts, loaders.WithCacheEngine(cacheEngine)) | ||
} | ||
|
||
return loaders.NewDocumentLoader(ipfsNode, "", opts...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package c_polygonid | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
core "github.com/iden3/go-iden3-core/v2" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestNewEnvConfigFromJSON(t *testing.T) { | ||
cfgJSON := `{ | ||
"ethereumUrl": "http://localhost:8545", | ||
"stateContractAddr": "0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655", | ||
"reverseHashServiceUrl": "http://localhost:8003", | ||
"ipfsNodeUrl": "http://localhost:5001", | ||
"chainConfigs": { | ||
"1": { | ||
"rpcUrl": "http://localhost:8545", | ||
"stateContractAddr": "0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655" | ||
}, | ||
"0x10": { | ||
"rpcUrl": "http://localhost:8546", | ||
"stateContractAddr": "0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655" | ||
}, | ||
"0X2835": { | ||
"rpcUrl": "http://localhost:8547", | ||
"stateContractAddr": "0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655" | ||
} | ||
}, | ||
"didMethods": [ | ||
{ | ||
"name": "ethr", | ||
"blockchain": "ethereum", | ||
"network": "mainnet", | ||
"networkFlag": 6, | ||
"methodByte": "0b010011", | ||
"chainID": "10293" | ||
} | ||
] | ||
}` | ||
cfg, err := NewEnvConfigFromJSON([]byte(cfgJSON)) | ||
require.NoError(t, err) | ||
|
||
require.Equal(t, | ||
EnvConfig{ | ||
DIDMethods: []MethodConfig{ | ||
{ | ||
MethodName: "ethr", | ||
Blockchain: "ethereum", | ||
NetworkID: "mainnet", | ||
NetworkFlag: 6, | ||
MethodByte: 19, | ||
ChainID: 10293, | ||
}, | ||
}, | ||
ChainConfigs: PerChainConfig{ | ||
1: { | ||
RPCUrl: "http://localhost:8545", | ||
StateContractAddr: common.HexToAddress("0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655"), | ||
}, | ||
16: { | ||
RPCUrl: "http://localhost:8546", | ||
StateContractAddr: common.HexToAddress("0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655"), | ||
}, | ||
10293: { | ||
RPCUrl: "http://localhost:8547", | ||
StateContractAddr: common.HexToAddress("0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655"), | ||
}, | ||
}, | ||
EthereumURL: "http://localhost:8545", | ||
StateContractAddr: common.HexToAddress("0xEA9aF2088B4a9770fC32A12fD42E61BDD317E655"), | ||
ReverseHashServiceUrl: "http://localhost:8003", | ||
IPFSNodeURL: "http://localhost:5001", | ||
}, | ||
cfg) | ||
|
||
// check that custom DID methods are registered | ||
chainID, err := core.GetChainID("ethereum", "mainnet") | ||
require.NoError(t, err) | ||
require.Equal(t, core.ChainID(10293), chainID) | ||
blockchain, networkID, err := core.NetworkByChainID(core.ChainID(10293)) | ||
require.NoError(t, err) | ||
require.Equal(t, core.Blockchain("ethereum"), blockchain) | ||
require.Equal(t, core.NetworkID("mainnet"), networkID) | ||
} |
Oops, something went wrong.