ethr-did-resolver
Advanced tools
Comparing version 4.3.3 to 4.3.4
@@ -48,1 +48,2 @@ import { Contract } from '@ethersproject/contracts'; | ||
export declare function configureResolverWithNetworks(conf?: ConfigurationOptions): ConfiguredNetworks; | ||
//# sourceMappingURL=configuration.d.ts.map |
@@ -33,1 +33,2 @@ import { Signer } from '@ethersproject/abstract-signer'; | ||
} | ||
//# sourceMappingURL=controller.d.ts.map |
@@ -79,1 +79,2 @@ import { BigNumber } from '@ethersproject/bignumber'; | ||
} | ||
//# sourceMappingURL=helpers.d.ts.map |
@@ -9,1 +9,2 @@ import { getResolver } from './resolver'; | ||
legacyAttrTypes as attrTypes, verificationMethodTypes, identifierMatcher, interpretIdentifier, Errors, }; | ||
//# sourceMappingURL=index.d.ts.map |
1150
lib/index.js
@@ -1,2 +0,1150 @@ | ||
var e=require("@ethersproject/basex"),t=require("@ethersproject/bignumber"),r=require("@ethersproject/contracts"),n=require("@ethersproject/providers"),o=require("ethr-did-registry"),i=require("@ethersproject/address"),c=require("@ethersproject/transactions"),s=require("querystring");function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var d=a(o);const u=/^(.*)?(0x[0-9a-fA-F]{40}|0x[0-9a-fA-F]{66})$/;var h,l;exports.verificationMethodTypes=void 0,(h=exports.verificationMethodTypes||(exports.verificationMethodTypes={})).EcdsaSecp256k1VerificationKey2019="EcdsaSecp256k1VerificationKey2019",h.EcdsaSecp256k1RecoveryMethod2020="EcdsaSecp256k1RecoveryMethod2020",h.Ed25519VerificationKey2018="Ed25519VerificationKey2018",h.RSAVerificationKey2018="RSAVerificationKey2018",h.X25519KeyAgreementKey2019="X25519KeyAgreementKey2019",function(e){e.DIDOwnerChanged="DIDOwnerChanged",e.DIDAttributeChanged="DIDAttributeChanged",e.DIDDelegateChanged="DIDDelegateChanged"}(l||(l={}));const f={sigAuth:"SignatureAuthentication2018",veriKey:"VerificationKey2018",enc:"KeyAgreementKey2019"},v={Secp256k1VerificationKey2018:exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019,Ed25519SignatureAuthentication2018:exports.verificationMethodTypes.Ed25519VerificationKey2018,Secp256k1SignatureAuthentication2018:exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019,RSAVerificationKey2018:exports.verificationMethodTypes.RSAVerificationKey2018,Ed25519VerificationKey2018:exports.verificationMethodTypes.Ed25519VerificationKey2018,X25519KeyAgreementKey2019:exports.verificationMethodTypes.X25519KeyAgreementKey2019};function m(e){return("string"==typeof e?Buffer.from(e.slice(2),"hex"):Buffer.from(e)).toString("utf8").replace(/\0+$/,"")}function p(e){const t="0x"+Buffer.from(e).slice(0,32).toString("hex");return t+"0".repeat(66-t.length)}function g(e){let t,r=e;if(r.startsWith("did:ethr")){r=r.split("?")[0];const e=r.split(":");r=e[e.length-1],e.length>=4&&(t=e.splice(2,e.length-3).join(":"))}return r.length>42?{address:c.computeAddress(r),publicKey:r,network:t}:{address:i.getAddress(r),network:t}}const y={mainnet:"0x1",ropsten:"0x3",rinkeby:"0x4",goerli:"0x5",kovan:"0x2a"},b={...y,rsk:"0x1e","rsk:testnet":"0x1f",artis_t1:"0x03c401",artis_s1:"0x03c301",matic:"0x89",maticmum:"0x13881"};var x;function w(e){var o;let i=e.provider||(null==(o=e.web3)?void 0:o.currentProvider);if(!i){if(!e.rpcUrl)throw new Error(`invalid_config: No web3 provider could be determined for network ${e.name||e.chainId}`);{var c;const r=e.chainId?e.chainId:b[e.name||""],o=r?t.BigNumber.from(r).toNumber():r,s=y[e.name||""]?null==(c=e.name)?void 0:c.replace("mainnet","homestead"):"any";i=new n.JsonRpcProvider(e.rpcUrl,o||s)}}return r.ContractFactory.fromSolidity(d.default).attach(e.registry||"0xdca7ef03e98e0dc2b855be647c39abe984fcf21b").connect(i)}function k(e){const t={},r=e.chainId||b[e.name||""];return r?(e.name&&(t[e.name]=w(e)),t["number"==typeof r?`0x${r.toString(16)}`:r]=w(e)):(e.provider||e.web3||e.rpcUrl)&&(t[e.name||""]=w(e)),t}function D(e){var t;return{...k(e),...null==(t=e.networks)?void 0:t.reduce((e,t)=>({...e,...k(t)}),{})}}exports.Errors=void 0,(x=exports.Errors||(exports.Errors={})).notFound="notFound",x.invalidDid="invalidDid",x.unknownNetwork="unknownNetwork";class P{constructor(e,t,r,n="mainnet",o,i,c="0xdca7ef03e98e0dc2b855be647c39abe984fcf21b"){const{address:s,publicKey:a,network:d}=g(e),u=d||n;if(t)this.contract=t;else{if(!(o||null!=r&&r.provider||i))throw new Error(" either a contract instance or a provider or rpcUrl is required to initialize");this.contract=w({name:u,provider:o||(null==r?void 0:r.provider),registry:c,rpcUrl:i})}this.signer=r,this.address=s;let h=u?`${u}:`:"";h in["mainnet:","0x1:"]&&(h=""),this.did=a?`did:ethr:${h}${a}`:`did:ethr:${h}${s}`}getOwner(e,t){try{return Promise.resolve(this.contract.functions.identityOwner(e,{blockTag:t})).then(function(e){return e[0]})}catch(e){return Promise.reject(e)}}attachContract(e){try{const t=this;return Promise.resolve(e||t.getOwner(t.address,"latest")).then(function(e){const r=t.signer?t.signer:t.contract.provider.getSigner(e)||t.contract.signer;return t.contract.connect(r)})}catch(e){return Promise.reject(e)}}changeOwner(e,t={}){try{const r=this,n={gasLimit:123456,gasPrice:1e9,...t};return Promise.resolve(r.attachContract(n.from)).then(function(t){return delete n.from,Promise.resolve(t.functions.changeOwner(r.address,e,n)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}addDelegate(e,t,r,n={}){try{const o=this,i={gasLimit:123456,gasPrice:1e9,...n};return Promise.resolve(o.attachContract(i.from)).then(function(n){delete i.from;const c=p(e);return Promise.resolve(n.functions.addDelegate(o.address,c,t,r,i)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}revokeDelegate(e,t,r={}){try{const n=this,o={gasLimit:123456,gasPrice:1e9,...r};return e=e.startsWith("0x")?e:p(e),Promise.resolve(n.attachContract(o.from)).then(function(r){return delete o.from,Promise.resolve(r.functions.revokeDelegate(n.address,e,t,o)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}setAttribute(e,t,r,n={}){try{const o=this,i={gasLimit:123456,gasPrice:1e9,controller:void 0,...n};return e=e.startsWith("0x")?e:p(e),t=t.startsWith("0x")?t:"0x"+Buffer.from(t,"utf-8").toString("hex"),Promise.resolve(o.attachContract(i.from)).then(function(n){return delete i.from,Promise.resolve(n.functions.setAttribute(o.address,e,t,r,i)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}revokeAttribute(e,t,r={}){try{const n=this,o={gasLimit:123456,gasPrice:1e9,...r};return e=e.startsWith("0x")?e:p(e),t=t.startsWith("0x")?t:"0x"+Buffer.from(t,"utf-8").toString("hex"),Promise.resolve(n.attachContract(o.from)).then(function(r){return delete o.from,Promise.resolve(r.functions.revokeAttribute(n.address,e,t,o)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}}function I(e,t,r){if(!e.s){if(r instanceof K){if(!r.s)return void(r.o=I.bind(null,e,t));1&t&&(t=r.s),r=r.v}if(r&&r.then)return void r.then(I.bind(null,e,t),I.bind(null,e,2));e.s=t,e.v=r;const n=e.o;n&&n(e)}}const K=function(){function e(){}return e.prototype.then=function(t,r){const n=new e,o=this.s;if(o){const e=1&o?t:r;if(e){try{I(n,1,e(this.v))}catch(e){I(n,2,e)}return n}return this}return this.o=function(e){try{const o=e.v;1&e.s?I(n,1,t?t(o):o):r?I(n,1,r(o)):I(n,2,o)}catch(e){I(n,2,e)}},n},e}();function S(e){return e instanceof K&&1&e.s}class N{constructor(e){this.contracts=function(e={}){const t={...(r=e.infuraProjectId,r?D({networks:[{name:"mainnet",chainId:"0x1",provider:new n.InfuraProvider("homestead",r)},{name:"ropsten",chainId:"0x3",provider:new n.InfuraProvider("ropsten",r)},{name:"rinkeby",chainId:"0x4",provider:new n.InfuraProvider("rinkeby",r)},{name:"goerli",chainId:"0x5",provider:new n.InfuraProvider("goerli",r)},{name:"kovan",chainId:"0x2a",provider:new n.InfuraProvider("kovan",r)}]}):{}),...D(e)};var r;if(0===Object.keys(t).length)throw new Error("invalid_config: Please make sure to have at least one network");return t}(e)}getOwner(e,t,r){try{return Promise.resolve(new P(e,this.contracts[t]).getOwner(e,r))}catch(e){return Promise.reject(e)}}previousChange(e,r,n){try{return Promise.resolve(this.contracts[r].functions.changed(e,{blockTag:n})).then(function(e){return t.BigNumber.from(e[0])})}catch(e){return Promise.reject(e)}}getBlockMetadata(e,t){try{return Promise.resolve(this.contracts[t].provider.getBlock(e)).then(function(e){return{height:e.number.toString(),isoDate:new Date(1e3*e.timestamp).toISOString().replace(".000","")}})}catch(e){return Promise.reject(e)}}changeLog(e,r,n="latest"){try{const o=this,i=o.contracts[r],c=i.provider,s=r.startsWith("0x")?r:b[r];return Promise.resolve(c.getNetwork()).then(function(a){const d=a.chainId,u=s?t.BigNumber.from(s).toNumber():d,h=[],{address:l,publicKey:f}=g(e),v=f;return Promise.resolve(o.previousChange(l,r,n)).then(function(e){function r(){return{address:l,history:h,controllerKey:v,chainId:u}}const n=function(e,t,r){for(var n;;){var o=e();if(S(o)&&(o=o.v),!o)return i;if(o.then){n=0;break}var i=r();if(i&&i.then){if(!S(i)){n=1;break}i=i.s}}var c=new K,s=I.bind(null,c,2);return(0===n?o.then(d):1===n?i.then(a):(void 0).then(function(){(o=e())?o.then?o.then(d).then(void 0,s):d(o):I(c,1,i)})).then(void 0,s),c;function a(t){i=t;do{if(!(o=e())||S(o)&&!o.v)return void I(c,1,i);if(o.then)return void o.then(d).then(void 0,s);S(i=r())&&(i=i.v)}while(!i||!i.then);i.then(a).then(void 0,s)}function d(e){e?(i=r())&&i.then?i.then(a).then(void 0,s):a(i):I(c,1,i)}}(function(){return!!e},0,function(){const r=e;return Promise.resolve(c.getLogs({address:i.address,topics:[null,`0x000000000000000000000000${l.slice(2)}`],fromBlock:e.toHexString(),toBlock:e.toHexString()})).then(function(n){const o=function(e,r){return r.map(r=>function(e,r){const n={};if(e.eventFragment.inputs.length!==e.args.length)throw new TypeError("malformed event input. wrong number of arguments");return e.eventFragment.inputs.forEach((r,o)=>{let i=e.args[o];"object"==typeof i&&(i=t.BigNumber.from(i)),"bytes32"===r.type&&(i=m(i)),n[r.name]=i}),n._eventName=e.name,n.blockNumber=r,n}(e.interface.parseLog(r),r.blockNumber))}(i,n);o.reverse(),e=null;for(const t of o)h.unshift(t),t.previousChange.lt(r)&&(e=t.previousChange)})});return n&&n.then?n.then(r):r()})})}catch(e){return Promise.reject(e)}}wrapDidDocument(r,n,o,i,c,s,a){var d;const u={"@context":["https://www.w3.org/ns/did/v1","https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld"],id:r,verificationMethod:[],authentication:[],assertionMethod:[]};let h=n;const m=[`${r}#controller`];let p=0,g=Number.POSITIVE_INFINITY,y=!1,b=0,x=0;const w={},k={},D={};for(const n of i){if(-1!==s&&n.blockNumber>s){g>n.blockNumber&&(g=n.blockNumber);continue}p<n.blockNumber&&(p=n.blockNumber);const o=n.validTo||t.BigNumber.from(0),i=`${n._eventName}-${n.delegateType||n.name}-${n.delegate||n.value}`;if(o&&o.gte(a)){if(n._eventName===l.DIDDelegateChanged){const e=n;switch(b++,e.delegateType){case"sigAuth":w[i]=`${r}#delegate-${b}`;case"veriKey":k[i]={id:`${r}#delegate-${b}`,type:exports.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020,controller:r,blockchainAccountId:`${e.delegate}@eip155:${c}`}}}else if(n._eventName===l.DIDAttributeChanged){const t=n,o=t.name.match(/^did\/(pub|svc)\/(\w+)(\/(\w+))?(\/(\w+))?$/);if(o){const n=o[2],c=f[o[4]]||o[4],s=o[6];switch(o[1]){case"pub":{b++;const a={id:`${r}#delegate-${b}`,type:`${n}${c}`,controller:r};switch(a.type=v[a.type]||n,s){case null:case void 0:case"hex":a.publicKeyHex=t.value.slice(2);break;case"base64":a.publicKeyBase64=Buffer.from(t.value.slice(2),"hex").toString("base64");break;case"base58":a.publicKeyBase58=e.Base58.encode(Buffer.from(t.value.slice(2),"hex"));break;case"pem":a.publicKeyPem=Buffer.from(t.value.slice(2),"hex").toString();break;default:a.value=t.value}k[i]=a,"sigAuth"===o[4]&&(w[i]=a.id);break}case"svc":x++,D[i]={id:`${r}#service-${x}`,type:n,serviceEndpoint:Buffer.from(t.value.slice(2),"hex").toString()}}}}}else if(n._eventName===l.DIDOwnerChanged){if(h=n.owner,"0x0000000000000000000000000000000000000000"===n.owner){y=!0;break}}else n._eventName===l.DIDDelegateChanged||n._eventName===l.DIDAttributeChanged&&n.name.match(/^did\/pub\//)?b++:n._eventName===l.DIDAttributeChanged&&n.name.match(/^did\/svc\//)&&x++,delete w[i],delete k[i],delete D[i]}const P=[{id:`${r}#controller`,type:exports.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020,controller:r,blockchainAccountId:`${h}@eip155:${c}`}];o&&h==n&&(P.push({id:`${r}#controllerKey`,type:exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019,controller:r,publicKeyHex:o}),m.push(`${r}#controllerKey`));const I={...u,verificationMethod:P.concat(Object.values(k)),authentication:m.concat(Object.values(w))};return Object.values(D).length>0&&(I.service=Object.values(D)),I.assertionMethod=[...(null==(d=I.verificationMethod)?void 0:d.map(e=>e.id))||[]],y?{didDocument:{...u,"@context":"https://www.w3.org/ns/did/v1"},deactivated:y,versionId:p,nextVersionId:g}:{didDocument:I,deactivated:y,versionId:p,nextVersionId:g}}resolve(e,r,n,o){try{const n=this;function i(){return Promise.resolve(n.changeLog(a,d,"latest")).then(function({address:t,history:r,controllerKey:o,chainId:i}){return function(c,s){try{var a=function(){function c(){function e(){return{didDocumentMetadata:{...v,...m,...p},didResolutionMetadata:{contentType:"application/did+ld+json"},didDocument:s}}const t=function(){if(f!==Number.POSITIVE_INFINITY)return Promise.resolve(n.getBlockMetadata(f,d)).then(function(e){p={nextVersionId:e.height,nextUpdate:e.isoDate}})}();return t&&t.then?t.then(e):e()}const{didDocument:s,deactivated:a,versionId:u,nextVersionId:f}=n.wrapDidDocument(e,t,o,r,i,h,l),v=a?{deactivated:!0}:{};let m={},p={};const g=function(){if(0!==u)return Promise.resolve(n.getBlockMetadata(u,d)).then(function(e){m={versionId:e.height,updated:e.isoDate}})}();return g&&g.then?g.then(c):c()}()}catch(e){return s(e)}return a&&a.then?a.then(void 0,s):a}(0,function(e){return{didResolutionMetadata:{error:exports.Errors.notFound,message:e.toString()},didDocumentMetadata:{},didDocument:null}})})}const c=r.id.match(u);if(!c)return Promise.resolve({didResolutionMetadata:{error:exports.Errors.invalidDid,message:`Not a valid did:ethr: ${r.id}`},didDocumentMetadata:{},didDocument:null});const a=c[2],d=c[1]?c[1].slice(0,-1):"mainnet";let h=o.blockTag||"latest";if("string"==typeof r.query){const e=s.decode(r.query);h="string"==typeof e.versionId?e.versionId:h;try{h=Number.parseInt(h)}catch(e){h="latest"}}if(!n.contracts[d])return Promise.resolve({didResolutionMetadata:{error:exports.Errors.unknownNetwork,message:`The DID resolver does not have a configuration for network: ${d}`},didDocumentMetadata:{},didDocument:null});let l=t.BigNumber.from(Math.floor((new Date).getTime()/1e3));const f=function(){if("number"==typeof h)return Promise.resolve(n.getBlockMetadata(h,d)).then(function(e){l=t.BigNumber.from(Date.parse(e.isoDate)/1e3)})}();return Promise.resolve(f&&f.then?f.then(i):i())}catch(e){return Promise.reject(e)}}build(){return{ethr:this.resolve.bind(this)}}}exports.EthrDidController=P,exports.REGISTRY="0xdca7ef03e98e0dc2b855be647c39abe984fcf21b",exports.attrTypes=f,exports.bytes32toString=m,exports.delegateTypes=v,exports.getResolver=function(e){return new N(e).build()},exports.identifierMatcher=u,exports.interpretIdentifier=g,exports.stringToBytes32=p; | ||
var basex = require('@ethersproject/basex'); | ||
var bignumber = require('@ethersproject/bignumber'); | ||
var contracts = require('@ethersproject/contracts'); | ||
var providers = require('@ethersproject/providers'); | ||
var DidRegistryContract = require('ethr-did-registry'); | ||
var address = require('@ethersproject/address'); | ||
var transactions = require('@ethersproject/transactions'); | ||
var qs = require('querystring'); | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
function _interopNamespace(e) { | ||
if (e && e.__esModule) return e; | ||
var n = Object.create(null); | ||
if (e) { | ||
Object.keys(e).forEach(function (k) { | ||
if (k !== 'default') { | ||
var d = Object.getOwnPropertyDescriptor(e, k); | ||
Object.defineProperty(n, k, d.get ? d : { | ||
enumerable: true, | ||
get: function () { | ||
return e[k]; | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
n['default'] = e; | ||
return n; | ||
} | ||
var DidRegistryContract__default = /*#__PURE__*/_interopDefaultLegacy(DidRegistryContract); | ||
var qs__namespace = /*#__PURE__*/_interopNamespace(qs); | ||
const identifierMatcher = /^(.*)?(0x[0-9a-fA-F]{40}|0x[0-9a-fA-F]{66})$/; | ||
const nullAddress = '0x0000000000000000000000000000000000000000'; | ||
const DEFAULT_REGISTRY_ADDRESS = '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b'; | ||
exports.verificationMethodTypes = void 0; | ||
(function (verificationMethodTypes) { | ||
verificationMethodTypes["EcdsaSecp256k1VerificationKey2019"] = "EcdsaSecp256k1VerificationKey2019"; | ||
verificationMethodTypes["EcdsaSecp256k1RecoveryMethod2020"] = "EcdsaSecp256k1RecoveryMethod2020"; | ||
verificationMethodTypes["Ed25519VerificationKey2018"] = "Ed25519VerificationKey2018"; | ||
verificationMethodTypes["RSAVerificationKey2018"] = "RSAVerificationKey2018"; | ||
verificationMethodTypes["X25519KeyAgreementKey2019"] = "X25519KeyAgreementKey2019"; | ||
})(exports.verificationMethodTypes || (exports.verificationMethodTypes = {})); | ||
var eventNames; | ||
(function (eventNames) { | ||
eventNames["DIDOwnerChanged"] = "DIDOwnerChanged"; | ||
eventNames["DIDAttributeChanged"] = "DIDAttributeChanged"; | ||
eventNames["DIDDelegateChanged"] = "DIDDelegateChanged"; | ||
})(eventNames || (eventNames = {})); | ||
const legacyAttrTypes = { | ||
sigAuth: 'SignatureAuthentication2018', | ||
veriKey: 'VerificationKey2018', | ||
enc: 'KeyAgreementKey2019' | ||
}; | ||
const legacyAlgoMap = { | ||
/**@deprecated */ | ||
Secp256k1VerificationKey2018: exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
/**@deprecated */ | ||
Ed25519SignatureAuthentication2018: exports.verificationMethodTypes.Ed25519VerificationKey2018, | ||
/**@deprecated */ | ||
Secp256k1SignatureAuthentication2018: exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
//keep legacy mapping | ||
RSAVerificationKey2018: exports.verificationMethodTypes.RSAVerificationKey2018, | ||
Ed25519VerificationKey2018: exports.verificationMethodTypes.Ed25519VerificationKey2018, | ||
X25519KeyAgreementKey2019: exports.verificationMethodTypes.X25519KeyAgreementKey2019 | ||
}; | ||
function bytes32toString(input) { | ||
const buff = typeof input === 'string' ? Buffer.from(input.slice(2), 'hex') : Buffer.from(input); | ||
return buff.toString('utf8').replace(/\0+$/, ''); | ||
} | ||
function stringToBytes32(str) { | ||
const buffStr = '0x' + Buffer.from(str).slice(0, 32).toString('hex'); | ||
return buffStr + '0'.repeat(66 - buffStr.length); | ||
} | ||
function interpretIdentifier(identifier) { | ||
let id = identifier; | ||
let network = undefined; | ||
if (id.startsWith('did:ethr')) { | ||
id = id.split('?')[0]; | ||
const components = id.split(':'); | ||
id = components[components.length - 1]; | ||
if (components.length >= 4) { | ||
network = components.splice(2, components.length - 3).join(':'); | ||
} | ||
} | ||
if (id.length > 42) { | ||
return { | ||
address: transactions.computeAddress(id), | ||
publicKey: id, | ||
network | ||
}; | ||
} else { | ||
return { | ||
address: address.getAddress(id), | ||
network | ||
}; // checksum address | ||
} | ||
} | ||
const knownInfuraNetworks = { | ||
mainnet: '0x1', | ||
ropsten: '0x3', | ||
rinkeby: '0x4', | ||
goerli: '0x5', | ||
kovan: '0x2a' | ||
}; | ||
const knownNetworks = { ...knownInfuraNetworks, | ||
rsk: '0x1e', | ||
'rsk:testnet': '0x1f', | ||
artis_t1: '0x03c401', | ||
artis_s1: '0x03c301', | ||
matic: '0x89', | ||
maticmum: '0x13881' | ||
}; | ||
exports.Errors = void 0; | ||
(function (Errors) { | ||
/** | ||
* The resolver has failed to construct the DID document. | ||
* This can be caused by a network issue, a wrong registry address or malformed logs while parsing the registry history. | ||
* Please inspect the `DIDResolutionMetadata.message` to debug further. | ||
*/ | ||
Errors["notFound"] = "notFound"; | ||
/** | ||
* The resolver does not know how to resolve the given DID. Most likely it is not a `did:ethr`. | ||
*/ | ||
Errors["invalidDid"] = "invalidDid"; | ||
/** | ||
* The resolver is misconfigured or is being asked to resolve a DID anchored on an unknown network | ||
*/ | ||
Errors["unknownNetwork"] = "unknownNetwork"; | ||
})(exports.Errors || (exports.Errors = {})); | ||
function configureNetworksWithInfura(projectId) { | ||
if (!projectId) { | ||
return {}; | ||
} | ||
const networks = [{ | ||
name: 'mainnet', | ||
chainId: '0x1', | ||
provider: new providers.InfuraProvider('homestead', projectId) | ||
}, { | ||
name: 'ropsten', | ||
chainId: '0x3', | ||
provider: new providers.InfuraProvider('ropsten', projectId) | ||
}, { | ||
name: 'rinkeby', | ||
chainId: '0x4', | ||
provider: new providers.InfuraProvider('rinkeby', projectId) | ||
}, { | ||
name: 'goerli', | ||
chainId: '0x5', | ||
provider: new providers.InfuraProvider('goerli', projectId) | ||
}, { | ||
name: 'kovan', | ||
chainId: '0x2a', | ||
provider: new providers.InfuraProvider('kovan', projectId) | ||
}]; | ||
return configureNetworks({ | ||
networks | ||
}); | ||
} | ||
function getContractForNetwork(conf) { | ||
var _conf$web; | ||
let provider = conf.provider || ((_conf$web = conf.web3) == null ? void 0 : _conf$web.currentProvider); | ||
if (!provider) { | ||
if (conf.rpcUrl) { | ||
var _conf$name; | ||
const chainIdRaw = conf.chainId ? conf.chainId : knownNetworks[conf.name || '']; | ||
const chainId = chainIdRaw ? bignumber.BigNumber.from(chainIdRaw).toNumber() : chainIdRaw; | ||
const networkName = knownInfuraNetworks[conf.name || ''] ? (_conf$name = conf.name) == null ? void 0 : _conf$name.replace('mainnet', 'homestead') : 'any'; | ||
provider = new providers.JsonRpcProvider(conf.rpcUrl, chainId || networkName); | ||
} else { | ||
throw new Error(`invalid_config: No web3 provider could be determined for network ${conf.name || conf.chainId}`); | ||
} | ||
} | ||
const contract = contracts.ContractFactory.fromSolidity(DidRegistryContract__default['default']).attach(conf.registry || DEFAULT_REGISTRY_ADDRESS).connect(provider); | ||
return contract; | ||
} | ||
function configureNetwork(net) { | ||
const networks = {}; | ||
const chainId = net.chainId || knownNetworks[net.name || '']; | ||
if (chainId) { | ||
if (net.name) { | ||
networks[net.name] = getContractForNetwork(net); | ||
} | ||
const id = typeof chainId === 'number' ? `0x${chainId.toString(16)}` : chainId; | ||
networks[id] = getContractForNetwork(net); | ||
} else if (net.provider || net.web3 || net.rpcUrl) { | ||
networks[net.name || ''] = getContractForNetwork(net); | ||
} | ||
return networks; | ||
} | ||
function configureNetworks(conf) { | ||
var _conf$networks; | ||
return { ...configureNetwork(conf), | ||
...((_conf$networks = conf.networks) == null ? void 0 : _conf$networks.reduce((networks, net) => { | ||
return { ...networks, | ||
...configureNetwork(net) | ||
}; | ||
}, {})) | ||
}; | ||
} | ||
/** | ||
* Generates a configuration that maps ethereum network names and chainIDs to the respective ERC1056 contracts deployed on them. | ||
* @returns a record of ERC1056 `Contract` instances | ||
* @param conf configuration options for the resolver. An array of network details. | ||
* Each network entry should contain at least one of `name` or `chainId` AND one of `provider`, `web3`, or `rpcUrl` | ||
* For convenience, you can also specify an `infuraProjectId` which will create a mapping for all the networks supported by https://infura.io. | ||
* @example ```js | ||
* [ | ||
* { name: 'development', registry: '0x9af37603e98e0dc2b855be647c39abe984fc2445', rpcUrl: 'http://127.0.0.1:8545/' }, | ||
* { name: 'goerli', chainId: 5, provider: new InfuraProvider('goerli') }, | ||
* { name: 'rinkeby', provider: new AlchemyProvider('rinkeby') }, | ||
* { name: 'rsk:testnet', chainId: '0x1f', rpcUrl: 'https://public-node.testnet.rsk.co' }, | ||
* ] | ||
* ``` | ||
*/ | ||
function configureResolverWithNetworks(conf = {}) { | ||
const networks = { ...configureNetworksWithInfura(conf.infuraProjectId), | ||
...configureNetworks(conf) | ||
}; | ||
if (Object.keys(networks).length === 0) { | ||
throw new Error('invalid_config: Please make sure to have at least one network'); | ||
} | ||
return networks; | ||
} | ||
/** | ||
* A class that can be used to interact with the ERC1056 contract on behalf of a local controller key-pair | ||
*/ | ||
class EthrDidController { | ||
/** | ||
* Creates an EthrDidController instance. | ||
* | ||
* @param identifier - required - a `did:ethr` string or a publicKeyHex or an ethereum address | ||
* @param signer - optional - a Signer that represents the current controller key (owner) of the identifier. If a 'signer' is not provided, then a 'contract' with an attached signer can be used. | ||
* @param contract - optional - a Contract instance representing a ERC1056 contract. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param chainNameOrId - optional - the network name or chainID, defaults to 'mainnet' | ||
* @param provider - optional - a web3 Provider. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param rpcUrl - optional - a JSON-RPC URL that can be used to connect to an ethereum network. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param registry - optional - The ERC1056 registry address. Defaults to '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b'. Only used with 'provider' or 'rpcUrl' | ||
*/ | ||
constructor(identifier, contract, signer, chainNameOrId = 'mainnet', provider, rpcUrl, registry = DEFAULT_REGISTRY_ADDRESS) { | ||
this.contract = void 0; | ||
this.signer = void 0; | ||
this.address = void 0; | ||
this.did = void 0; | ||
// initialize identifier | ||
const { | ||
address, | ||
publicKey, | ||
network | ||
} = interpretIdentifier(identifier); | ||
const net = network || chainNameOrId; // initialize contract connection | ||
if (contract) { | ||
this.contract = contract; | ||
} else if (provider || signer != null && signer.provider || rpcUrl) { | ||
const prov = provider || (signer == null ? void 0 : signer.provider); | ||
this.contract = getContractForNetwork({ | ||
name: net, | ||
provider: prov, | ||
registry, | ||
rpcUrl | ||
}); | ||
} else { | ||
throw new Error(' either a contract instance or a provider or rpcUrl is required to initialize'); | ||
} | ||
this.signer = signer; | ||
this.address = address; | ||
let networkString = net ? `${net}:` : ''; | ||
if (networkString in ['mainnet:', '0x1:']) { | ||
networkString = ''; | ||
} | ||
this.did = publicKey ? `did:ethr:${networkString}${publicKey}` : `did:ethr:${networkString}${address}`; | ||
} | ||
getOwner(address, blockTag) { | ||
try { | ||
const _this = this; | ||
return Promise.resolve(_this.contract.functions.identityOwner(address, { | ||
blockTag | ||
})).then(function (result) { | ||
return result[0]; | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
attachContract(controller) { | ||
try { | ||
const _this2 = this; | ||
return Promise.resolve(controller ? controller : _this2.getOwner(_this2.address, 'latest')).then(function (currentOwner) { | ||
const signer = _this2.signer ? _this2.signer : _this2.contract.provider.getSigner(currentOwner) || _this2.contract.signer; | ||
return _this2.contract.connect(signer); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
changeOwner(newOwner, options = {}) { | ||
try { | ||
const _this3 = this; | ||
// console.log(`changing owner for ${oldOwner} on registry at ${registryContract.address}`) | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
return Promise.resolve(_this3.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.changeOwner(_this3.address, newOwner, overrides)).then(function (ownerChange) { | ||
return Promise.resolve(ownerChange.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
addDelegate(delegateType, delegateAddress, exp, options = {}) { | ||
try { | ||
const _this4 = this; | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
return Promise.resolve(_this4.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
const delegateTypeBytes = stringToBytes32(delegateType); | ||
return Promise.resolve(contract.functions.addDelegate(_this4.address, delegateTypeBytes, delegateAddress, exp, overrides)).then(function (addDelegateTx) { | ||
addDelegateTx; | ||
return Promise.resolve(addDelegateTx.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
revokeDelegate(delegateType, delegateAddress, options = {}) { | ||
try { | ||
const _this5 = this; | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
delegateType = delegateType.startsWith('0x') ? delegateType : stringToBytes32(delegateType); | ||
return Promise.resolve(_this5.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.revokeDelegate(_this5.address, delegateType, delegateAddress, overrides)).then(function (addDelegateTx) { | ||
return Promise.resolve(addDelegateTx.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
setAttribute(attrName, attrValue, exp, options = {}) { | ||
try { | ||
const _this6 = this; | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
controller: undefined, | ||
...options | ||
}; | ||
attrName = attrName.startsWith('0x') ? attrName : stringToBytes32(attrName); | ||
attrValue = attrValue.startsWith('0x') ? attrValue : '0x' + Buffer.from(attrValue, 'utf-8').toString('hex'); | ||
return Promise.resolve(_this6.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.setAttribute(_this6.address, attrName, attrValue, exp, overrides)).then(function (setAttrTx) { | ||
return Promise.resolve(setAttrTx.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
revokeAttribute(attrName, attrValue, options = {}) { | ||
try { | ||
const _this7 = this; | ||
// console.log(`revoking attribute ${attrName}(${attrValue}) for ${identity}`) | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
attrName = attrName.startsWith('0x') ? attrName : stringToBytes32(attrName); | ||
attrValue = attrValue.startsWith('0x') ? attrValue : '0x' + Buffer.from(attrValue, 'utf-8').toString('hex'); | ||
return Promise.resolve(_this7.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.revokeAttribute(_this7.address, attrName, attrValue, overrides)).then(function (revokeAttributeTX) { | ||
return Promise.resolve(revokeAttributeTX.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
} | ||
function populateEventMetaClass(logResult, blockNumber) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const result = {}; | ||
if (logResult.eventFragment.inputs.length !== logResult.args.length) { | ||
throw new TypeError('malformed event input. wrong number of arguments'); | ||
} | ||
logResult.eventFragment.inputs.forEach((input, index) => { | ||
let val = logResult.args[index]; | ||
if (typeof val === 'object') { | ||
val = bignumber.BigNumber.from(val); | ||
} | ||
if (input.type === 'bytes32') { | ||
val = bytes32toString(val); | ||
} | ||
result[input.name] = val; | ||
}); | ||
result._eventName = logResult.name; | ||
result.blockNumber = blockNumber; | ||
return result; | ||
} | ||
function logDecoder(contract, logs) { | ||
const results = logs.map(log => { | ||
const res = contract.interface.parseLog(log); | ||
const event = populateEventMetaClass(res, log.blockNumber); | ||
return event; | ||
}); | ||
return results; | ||
} | ||
function _settle(pact, state, value) { | ||
if (!pact.s) { | ||
if (value instanceof _Pact) { | ||
if (value.s) { | ||
if (state & 1) { | ||
state = value.s; | ||
} | ||
value = value.v; | ||
} else { | ||
value.o = _settle.bind(null, pact, state); | ||
return; | ||
} | ||
} | ||
if (value && value.then) { | ||
value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2)); | ||
return; | ||
} | ||
pact.s = state; | ||
pact.v = value; | ||
const observer = pact.o; | ||
if (observer) { | ||
observer(pact); | ||
} | ||
} | ||
} | ||
const _Pact = /*#__PURE__*/function () { | ||
function _Pact() {} | ||
_Pact.prototype.then = function (onFulfilled, onRejected) { | ||
const result = new _Pact(); | ||
const state = this.s; | ||
if (state) { | ||
const callback = state & 1 ? onFulfilled : onRejected; | ||
if (callback) { | ||
try { | ||
_settle(result, 1, callback(this.v)); | ||
} catch (e) { | ||
_settle(result, 2, e); | ||
} | ||
return result; | ||
} else { | ||
return this; | ||
} | ||
} | ||
this.o = function (_this) { | ||
try { | ||
const value = _this.v; | ||
if (_this.s & 1) { | ||
_settle(result, 1, onFulfilled ? onFulfilled(value) : value); | ||
} else if (onRejected) { | ||
_settle(result, 1, onRejected(value)); | ||
} else { | ||
_settle(result, 2, value); | ||
} | ||
} catch (e) { | ||
_settle(result, 2, e); | ||
} | ||
}; | ||
return result; | ||
}; | ||
return _Pact; | ||
}(); | ||
function _isSettledPact(thenable) { | ||
return thenable instanceof _Pact && thenable.s & 1; | ||
} | ||
function _for(test, update, body) { | ||
var stage; | ||
for (;;) { | ||
var shouldContinue = test(); | ||
if (_isSettledPact(shouldContinue)) { | ||
shouldContinue = shouldContinue.v; | ||
} | ||
if (!shouldContinue) { | ||
return result; | ||
} | ||
if (shouldContinue.then) { | ||
stage = 0; | ||
break; | ||
} | ||
var result = body(); | ||
if (result && result.then) { | ||
if (_isSettledPact(result)) { | ||
result = result.s; | ||
} else { | ||
stage = 1; | ||
break; | ||
} | ||
} | ||
if (update) { | ||
var updateValue = update(); | ||
if (updateValue && updateValue.then && !_isSettledPact(updateValue)) { | ||
stage = 2; | ||
break; | ||
} | ||
} | ||
} | ||
var pact = new _Pact(); | ||
var reject = _settle.bind(null, pact, 2); | ||
(stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject); | ||
return pact; | ||
function _resumeAfterBody(value) { | ||
result = value; | ||
do { | ||
if (update) { | ||
updateValue = update(); | ||
if (updateValue && updateValue.then && !_isSettledPact(updateValue)) { | ||
updateValue.then(_resumeAfterUpdate).then(void 0, reject); | ||
return; | ||
} | ||
} | ||
shouldContinue = test(); | ||
if (!shouldContinue || _isSettledPact(shouldContinue) && !shouldContinue.v) { | ||
_settle(pact, 1, result); | ||
return; | ||
} | ||
if (shouldContinue.then) { | ||
shouldContinue.then(_resumeAfterTest).then(void 0, reject); | ||
return; | ||
} | ||
result = body(); | ||
if (_isSettledPact(result)) { | ||
result = result.v; | ||
} | ||
} while (!result || !result.then); | ||
result.then(_resumeAfterBody).then(void 0, reject); | ||
} | ||
function _resumeAfterTest(shouldContinue) { | ||
if (shouldContinue) { | ||
result = body(); | ||
if (result && result.then) { | ||
result.then(_resumeAfterBody).then(void 0, reject); | ||
} else { | ||
_resumeAfterBody(result); | ||
} | ||
} else { | ||
_settle(pact, 1, result); | ||
} | ||
} | ||
function _resumeAfterUpdate() { | ||
if (shouldContinue = test()) { | ||
if (shouldContinue.then) { | ||
shouldContinue.then(_resumeAfterTest).then(void 0, reject); | ||
} else { | ||
_resumeAfterTest(shouldContinue); | ||
} | ||
} else { | ||
_settle(pact, 1, result); | ||
} | ||
} | ||
} | ||
function _catch(body, recover) { | ||
try { | ||
var result = body(); | ||
} catch (e) { | ||
return recover(e); | ||
} | ||
if (result && result.then) { | ||
return result.then(void 0, recover); | ||
} | ||
return result; | ||
} | ||
function getResolver(options) { | ||
return new EthrDidResolver(options).build(); | ||
} | ||
class EthrDidResolver { | ||
constructor(options) { | ||
this.contracts = void 0; | ||
this.contracts = configureResolverWithNetworks(options); | ||
} | ||
/** | ||
* returns the current owner of a DID (represented by an address or public key) | ||
* | ||
* @param address | ||
*/ | ||
getOwner(address, networkId, blockTag) { | ||
try { | ||
const _this = this; | ||
//TODO: check if address or public key | ||
return Promise.resolve(new EthrDidController(address, _this.contracts[networkId]).getOwner(address, blockTag)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
/** | ||
* returns the previous change | ||
* | ||
* @param address | ||
*/ | ||
previousChange(address, networkId, blockTag) { | ||
try { | ||
const _this2 = this; | ||
return Promise.resolve(_this2.contracts[networkId].functions.changed(address, { | ||
blockTag | ||
})).then(function (result) { | ||
// console.log(`last change result: '${BigNumber.from(result['0'])}'`) | ||
return bignumber.BigNumber.from(result['0']); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
getBlockMetadata(blockHeight, networkId) { | ||
try { | ||
const _this3 = this; | ||
return Promise.resolve(_this3.contracts[networkId].provider.getBlock(blockHeight)).then(function (block) { | ||
return { | ||
height: block.number.toString(), | ||
isoDate: new Date(block.timestamp * 1000).toISOString().replace('.000', '') | ||
}; | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
changeLog(identity, networkId, blockTag = 'latest') { | ||
try { | ||
const _this4 = this; | ||
function _temp3(_provider$getNetwork) { | ||
const chainId = hexChainId ? _provider$getNetwork : _provider$getNetwork.chainId; | ||
const history = []; | ||
const { | ||
address, | ||
publicKey | ||
} = interpretIdentifier(identity); | ||
const controllerKey = publicKey; | ||
return Promise.resolve(_this4.previousChange(address, networkId, blockTag)).then(function (previousChange) { | ||
function _temp2() { | ||
return { | ||
address, | ||
history, | ||
controllerKey, | ||
chainId | ||
}; | ||
} | ||
const _temp = _for(function () { | ||
return !!previousChange; | ||
}, void 0, function () { | ||
const blockNumber = previousChange; // console.log(`gigel ${previousChange}`) | ||
return Promise.resolve(provider.getLogs({ | ||
address: contract.address, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
topics: [null, `0x000000000000000000000000${address.slice(2)}`], | ||
fromBlock: previousChange.toHexString(), | ||
toBlock: previousChange.toHexString() | ||
})).then(function (logs) { | ||
const events = logDecoder(contract, logs); | ||
events.reverse(); | ||
previousChange = null; | ||
for (const event of events) { | ||
history.unshift(event); | ||
if (event.previousChange.lt(blockNumber)) { | ||
previousChange = event.previousChange; | ||
} | ||
} | ||
}); | ||
}); | ||
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp); | ||
}); | ||
} | ||
const contract = _this4.contracts[networkId]; | ||
const provider = contract.provider; | ||
const hexChainId = networkId.startsWith('0x') ? networkId : knownNetworks[networkId]; //TODO: this can be used to check if the configuration is ok | ||
return Promise.resolve(hexChainId ? _temp3(bignumber.BigNumber.from(hexChainId).toNumber()) : Promise.resolve(provider.getNetwork()).then(_temp3)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
wrapDidDocument(did, address, controllerKey, history, chainId, blockHeight, now) { | ||
var _didDocument$verifica; | ||
const baseDIDDocument = { | ||
'@context': ['https://www.w3.org/ns/did/v1', 'https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld'], | ||
id: did, | ||
verificationMethod: [], | ||
authentication: [], | ||
assertionMethod: [] | ||
}; | ||
let controller = address; | ||
const authentication = [`${did}#controller`]; | ||
let versionId = 0; | ||
let nextVersionId = Number.POSITIVE_INFINITY; | ||
let deactivated = false; | ||
let delegateCount = 0; | ||
let serviceCount = 0; | ||
const auth = {}; | ||
const pks = {}; | ||
const services = {}; | ||
for (const event of history) { | ||
if (blockHeight !== -1 && event.blockNumber > blockHeight) { | ||
if (nextVersionId > event.blockNumber) { | ||
nextVersionId = event.blockNumber; | ||
} | ||
continue; | ||
} else { | ||
if (versionId < event.blockNumber) { | ||
versionId = event.blockNumber; | ||
} | ||
} | ||
const validTo = event.validTo || bignumber.BigNumber.from(0); | ||
const eventIndex = `${event._eventName}-${event.delegateType || event.name}-${event.delegate || event.value}`; | ||
if (validTo && validTo.gte(now)) { | ||
if (event._eventName === eventNames.DIDDelegateChanged) { | ||
const currentEvent = event; | ||
delegateCount++; | ||
const delegateType = currentEvent.delegateType; //conversion from bytes32 is done in logParser | ||
switch (delegateType) { | ||
case 'sigAuth': | ||
auth[eventIndex] = `${did}#delegate-${delegateCount}`; | ||
// eslint-disable-line no-fallthrough | ||
case 'veriKey': | ||
pks[eventIndex] = { | ||
id: `${did}#delegate-${delegateCount}`, | ||
type: exports.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020, | ||
controller: did, | ||
blockchainAccountId: `${currentEvent.delegate}@eip155:${chainId}` | ||
}; | ||
break; | ||
} | ||
} else if (event._eventName === eventNames.DIDAttributeChanged) { | ||
const currentEvent = event; | ||
const name = currentEvent.name; //conversion from bytes32 is done in logParser | ||
const match = name.match(/^did\/(pub|svc)\/(\w+)(\/(\w+))?(\/(\w+))?$/); | ||
if (match) { | ||
const section = match[1]; | ||
const algorithm = match[2]; | ||
const type = legacyAttrTypes[match[4]] || match[4]; | ||
const encoding = match[6]; | ||
switch (section) { | ||
case 'pub': | ||
{ | ||
delegateCount++; | ||
const pk = { | ||
id: `${did}#delegate-${delegateCount}`, | ||
type: `${algorithm}${type}`, | ||
controller: did | ||
}; | ||
pk.type = legacyAlgoMap[pk.type] || algorithm; | ||
switch (encoding) { | ||
case null: | ||
case undefined: | ||
case 'hex': | ||
pk.publicKeyHex = currentEvent.value.slice(2); | ||
break; | ||
case 'base64': | ||
pk.publicKeyBase64 = Buffer.from(currentEvent.value.slice(2), 'hex').toString('base64'); | ||
break; | ||
case 'base58': | ||
pk.publicKeyBase58 = basex.Base58.encode(Buffer.from(currentEvent.value.slice(2), 'hex')); | ||
break; | ||
case 'pem': | ||
pk.publicKeyPem = Buffer.from(currentEvent.value.slice(2), 'hex').toString(); | ||
break; | ||
default: | ||
pk.value = currentEvent.value; | ||
} | ||
pks[eventIndex] = pk; | ||
if (match[4] === 'sigAuth') { | ||
auth[eventIndex] = pk.id; | ||
} | ||
break; | ||
} | ||
case 'svc': | ||
serviceCount++; | ||
services[eventIndex] = { | ||
id: `${did}#service-${serviceCount}`, | ||
type: algorithm, | ||
serviceEndpoint: Buffer.from(currentEvent.value.slice(2), 'hex').toString() | ||
}; | ||
break; | ||
} | ||
} | ||
} | ||
} else if (event._eventName === eventNames.DIDOwnerChanged) { | ||
const currentEvent = event; | ||
controller = currentEvent.owner; | ||
if (currentEvent.owner === nullAddress) { | ||
deactivated = true; | ||
break; | ||
} | ||
} else { | ||
if (event._eventName === eventNames.DIDDelegateChanged || event._eventName === eventNames.DIDAttributeChanged && event.name.match(/^did\/pub\//)) { | ||
delegateCount++; | ||
} else if (event._eventName === eventNames.DIDAttributeChanged && event.name.match(/^did\/svc\//)) { | ||
serviceCount++; | ||
} | ||
delete auth[eventIndex]; | ||
delete pks[eventIndex]; | ||
delete services[eventIndex]; | ||
} | ||
} | ||
const publicKeys = [{ | ||
id: `${did}#controller`, | ||
type: exports.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020, | ||
controller: did, | ||
blockchainAccountId: `${controller}@eip155:${chainId}` | ||
}]; | ||
if (controllerKey && controller == address) { | ||
publicKeys.push({ | ||
id: `${did}#controllerKey`, | ||
type: exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
controller: did, | ||
publicKeyHex: controllerKey | ||
}); | ||
authentication.push(`${did}#controllerKey`); | ||
} | ||
const didDocument = { ...baseDIDDocument, | ||
verificationMethod: publicKeys.concat(Object.values(pks)), | ||
authentication: authentication.concat(Object.values(auth)) | ||
}; | ||
if (Object.values(services).length > 0) { | ||
didDocument.service = Object.values(services); | ||
} | ||
didDocument.assertionMethod = [...(((_didDocument$verifica = didDocument.verificationMethod) == null ? void 0 : _didDocument$verifica.map(pk => pk.id)) || [])]; | ||
return deactivated ? { | ||
didDocument: { ...baseDIDDocument, | ||
'@context': 'https://www.w3.org/ns/did/v1' | ||
}, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
} : { | ||
didDocument, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
}; | ||
} | ||
resolve(did, parsed, // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_unused, options) { | ||
try { | ||
const _this5 = this; | ||
function _temp9() { | ||
return Promise.resolve(_this5.changeLog(id, networkId, 'latest')).then(function ({ | ||
address, | ||
history, | ||
controllerKey, | ||
chainId | ||
}) { | ||
return _catch(function () { | ||
function _temp7() { | ||
function _temp5() { | ||
return { | ||
didDocumentMetadata: { ...status, | ||
...versionMeta, | ||
...versionMetaNext | ||
}, | ||
didResolutionMetadata: { | ||
contentType: 'application/did+ld+json' | ||
}, | ||
didDocument | ||
}; | ||
} | ||
const _temp4 = function () { | ||
if (nextVersionId !== Number.POSITIVE_INFINITY) { | ||
return Promise.resolve(_this5.getBlockMetadata(nextVersionId, networkId)).then(function (block) { | ||
versionMetaNext = { | ||
nextVersionId: block.height, | ||
nextUpdate: block.isoDate | ||
}; | ||
}); | ||
} | ||
}(); | ||
return _temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4); | ||
} | ||
const { | ||
didDocument, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
} = _this5.wrapDidDocument(did, address, controllerKey, history, chainId, blockTag, now); | ||
const status = deactivated ? { | ||
deactivated: true | ||
} : {}; | ||
let versionMeta = {}; | ||
let versionMetaNext = {}; | ||
const _temp6 = function () { | ||
if (versionId !== 0) { | ||
return Promise.resolve(_this5.getBlockMetadata(versionId, networkId)).then(function (block) { | ||
versionMeta = { | ||
versionId: block.height, | ||
updated: block.isoDate | ||
}; | ||
}); | ||
} | ||
}(); | ||
return _temp6 && _temp6.then ? _temp6.then(_temp7) : _temp7(_temp6); | ||
}, function (e) { | ||
return { | ||
didResolutionMetadata: { | ||
error: exports.Errors.notFound, | ||
message: e.toString() // This is not in spec, nut may be helpful | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}; | ||
}); | ||
}); | ||
} | ||
const fullId = parsed.id.match(identifierMatcher); | ||
if (!fullId) { | ||
return Promise.resolve({ | ||
didResolutionMetadata: { | ||
error: exports.Errors.invalidDid, | ||
message: `Not a valid did:ethr: ${parsed.id}` | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}); | ||
} | ||
const id = fullId[2]; | ||
const networkId = !fullId[1] ? 'mainnet' : fullId[1].slice(0, -1); | ||
let blockTag = options.blockTag || 'latest'; | ||
if (typeof parsed.query === 'string') { | ||
const qParams = qs__namespace.decode(parsed.query); | ||
blockTag = typeof qParams['versionId'] === 'string' ? qParams['versionId'] : blockTag; | ||
try { | ||
blockTag = Number.parseInt(blockTag); | ||
} catch (e) { | ||
blockTag = 'latest'; // invalid versionId parameters are ignored | ||
} | ||
} | ||
if (!_this5.contracts[networkId]) { | ||
return Promise.resolve({ | ||
didResolutionMetadata: { | ||
error: exports.Errors.unknownNetwork, | ||
message: `The DID resolver does not have a configuration for network: ${networkId}` | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}); | ||
} | ||
let now = bignumber.BigNumber.from(Math.floor(new Date().getTime() / 1000)); | ||
const _temp8 = function () { | ||
if (typeof blockTag === 'number') { | ||
return Promise.resolve(_this5.getBlockMetadata(blockTag, networkId)).then(function (block) { | ||
now = bignumber.BigNumber.from(Date.parse(block.isoDate) / 1000); | ||
}); | ||
} | ||
}(); | ||
return Promise.resolve(_temp8 && _temp8.then ? _temp8.then(_temp9) : _temp9(_temp8)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
build() { | ||
return { | ||
ethr: this.resolve.bind(this) | ||
}; | ||
} | ||
} | ||
exports.EthrDidController = EthrDidController; | ||
exports.REGISTRY = DEFAULT_REGISTRY_ADDRESS; | ||
exports.attrTypes = legacyAttrTypes; | ||
exports.bytes32toString = bytes32toString; | ||
exports.delegateTypes = legacyAlgoMap; | ||
exports.getResolver = getResolver; | ||
exports.identifierMatcher = identifierMatcher; | ||
exports.interpretIdentifier = interpretIdentifier; | ||
exports.stringToBytes32 = stringToBytes32; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,803 @@ | ||
import{Base58 as e}from"@ethersproject/basex";import{BigNumber as t}from"@ethersproject/bignumber";import{ContractFactory as r}from"@ethersproject/contracts";import{JsonRpcProvider as n,InfuraProvider as i}from"@ethersproject/providers";import a from"ethr-did-registry";import{getAddress as o}from"@ethersproject/address";import{computeAddress as c}from"@ethersproject/transactions";import{decode as s}from"querystring";function d(){return(d=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}const l=/^(.*)?(0x[0-9a-fA-F]{40}|0x[0-9a-fA-F]{66})$/,u="0xdca7ef03e98e0dc2b855be647c39abe984fcf21b";var h,f;!function(e){e.EcdsaSecp256k1VerificationKey2019="EcdsaSecp256k1VerificationKey2019",e.EcdsaSecp256k1RecoveryMethod2020="EcdsaSecp256k1RecoveryMethod2020",e.Ed25519VerificationKey2018="Ed25519VerificationKey2018",e.RSAVerificationKey2018="RSAVerificationKey2018",e.X25519KeyAgreementKey2019="X25519KeyAgreementKey2019"}(h||(h={})),function(e){e.DIDOwnerChanged="DIDOwnerChanged",e.DIDAttributeChanged="DIDAttributeChanged",e.DIDDelegateChanged="DIDDelegateChanged"}(f||(f={}));const m={sigAuth:"SignatureAuthentication2018",veriKey:"VerificationKey2018",enc:"KeyAgreementKey2019"},g={Secp256k1VerificationKey2018:h.EcdsaSecp256k1VerificationKey2019,Ed25519SignatureAuthentication2018:h.Ed25519VerificationKey2018,Secp256k1SignatureAuthentication2018:h.EcdsaSecp256k1VerificationKey2019,RSAVerificationKey2018:h.RSAVerificationKey2018,Ed25519VerificationKey2018:h.Ed25519VerificationKey2018,X25519KeyAgreementKey2019:h.X25519KeyAgreementKey2019};function p(e){return("string"==typeof e?Buffer.from(e.slice(2),"hex"):Buffer.from(e)).toString("utf8").replace(/\0+$/,"")}function v(e){const t="0x"+Buffer.from(e).slice(0,32).toString("hex");return t+"0".repeat(66-t.length)}function y(e){let t,r=e;if(r.startsWith("did:ethr")){r=r.split("?")[0];const e=r.split(":");r=e[e.length-1],e.length>=4&&(t=e.splice(2,e.length-3).join(":"))}return r.length>42?{address:c(r),publicKey:r,network:t}:{address:o(r),network:t}}const w={mainnet:"0x1",ropsten:"0x3",rinkeby:"0x4",goerli:"0x5",kovan:"0x2a"},b=d({},w,{rsk:"0x1e","rsk:testnet":"0x1f",artis_t1:"0x03c401",artis_s1:"0x03c301",matic:"0x89",maticmum:"0x13881"});var k;function D(e){var i;let o=e.provider||(null==(i=e.web3)?void 0:i.currentProvider);if(!o){if(!e.rpcUrl)throw new Error(`invalid_config: No web3 provider could be determined for network ${e.name||e.chainId}`);{var c;const r=e.chainId?e.chainId:b[e.name||""],i=r?t.from(r).toNumber():r,a=w[e.name||""]?null==(c=e.name)?void 0:c.replace("mainnet","homestead"):"any";o=new n(e.rpcUrl,i||a)}}return r.fromSolidity(a).attach(e.registry||"0xdca7ef03e98e0dc2b855be647c39abe984fcf21b").connect(o)}function x(e){const t={},r=e.chainId||b[e.name||""];return r?(e.name&&(t[e.name]=D(e)),t["number"==typeof r?`0x${r.toString(16)}`:r]=D(e)):(e.provider||e.web3||e.rpcUrl)&&(t[e.name||""]=D(e)),t}function I(e){var t;return d({},x(e),null==(t=e.networks)?void 0:t.reduce((e,t)=>d({},e,x(t)),{}))}!function(e){e.notFound="notFound",e.invalidDid="invalidDid",e.unknownNetwork="unknownNetwork"}(k||(k={}));class K{constructor(e,t,r,n="mainnet",i,a,o="0xdca7ef03e98e0dc2b855be647c39abe984fcf21b"){const{address:c,publicKey:s,network:d}=y(e),l=d||n;if(t)this.contract=t;else{if(!(i||null!=r&&r.provider||a))throw new Error(" either a contract instance or a provider or rpcUrl is required to initialize");this.contract=D({name:l,provider:i||(null==r?void 0:r.provider),registry:o,rpcUrl:a})}this.signer=r,this.address=c;let u=l?`${l}:`:"";u in["mainnet:","0x1:"]&&(u=""),this.did=s?`did:ethr:${u}${s}`:`did:ethr:${u}${c}`}async getOwner(e,t){return(await this.contract.functions.identityOwner(e,{blockTag:t}))[0]}async attachContract(e){const t=e?await e:await this.getOwner(this.address,"latest"),r=this.signer?this.signer:this.contract.provider.getSigner(t)||this.contract.signer;return this.contract.connect(r)}async changeOwner(e,t={}){const r=d({gasLimit:123456,gasPrice:1e9},t),n=await this.attachContract(r.from);delete r.from;const i=await n.functions.changeOwner(this.address,e,r);return await i.wait()}async addDelegate(e,t,r,n={}){const i=d({gasLimit:123456,gasPrice:1e9},n),a=await this.attachContract(i.from);delete i.from;const o=v(e),c=await a.functions.addDelegate(this.address,o,t,r,i);return await c.wait()}async revokeDelegate(e,t,r={}){const n=d({gasLimit:123456,gasPrice:1e9},r);e=e.startsWith("0x")?e:v(e);const i=await this.attachContract(n.from);delete n.from;const a=await i.functions.revokeDelegate(this.address,e,t,n);return await a.wait()}async setAttribute(e,t,r,n={}){const i=d({gasLimit:123456,gasPrice:1e9,controller:void 0},n);e=e.startsWith("0x")?e:v(e),t=t.startsWith("0x")?t:"0x"+Buffer.from(t,"utf-8").toString("hex");const a=await this.attachContract(i.from);delete i.from;const o=await a.functions.setAttribute(this.address,e,t,r,i);return await o.wait()}async revokeAttribute(e,t,r={}){const n=d({gasLimit:123456,gasPrice:1e9},r);e=e.startsWith("0x")?e:v(e),t=t.startsWith("0x")?t:"0x"+Buffer.from(t,"utf-8").toString("hex");const i=await this.attachContract(n.from);delete n.from;const a=await i.functions.revokeAttribute(this.address,e,t,n);return await a.wait()}}function S(e,r){return r.map(r=>function(e,r){const n={};if(e.eventFragment.inputs.length!==e.args.length)throw new TypeError("malformed event input. wrong number of arguments");return e.eventFragment.inputs.forEach((r,i)=>{let a=e.args[i];"object"==typeof a&&(a=t.from(a)),"bytes32"===r.type&&(a=p(a)),n[r.name]=a}),n._eventName=e.name,n.blockNumber=r,n}(e.interface.parseLog(r),r.blockNumber))}function $(e){return new N(e).build()}class N{constructor(e){this.contracts=function(e={}){const t=d({},(r=e.infuraProjectId)?I({networks:[{name:"mainnet",chainId:"0x1",provider:new i("homestead",r)},{name:"ropsten",chainId:"0x3",provider:new i("ropsten",r)},{name:"rinkeby",chainId:"0x4",provider:new i("rinkeby",r)},{name:"goerli",chainId:"0x5",provider:new i("goerli",r)},{name:"kovan",chainId:"0x2a",provider:new i("kovan",r)}]}):{},I(e));var r;if(0===Object.keys(t).length)throw new Error("invalid_config: Please make sure to have at least one network");return t}(e)}async getOwner(e,t,r){return new K(e,this.contracts[t]).getOwner(e,r)}async previousChange(e,r,n){const i=await this.contracts[r].functions.changed(e,{blockTag:n});return t.from(i[0])}async getBlockMetadata(e,t){const r=await this.contracts[t].provider.getBlock(e);return{height:r.number.toString(),isoDate:new Date(1e3*r.timestamp).toISOString().replace(".000","")}}async changeLog(e,r,n="latest"){const i=this.contracts[r],a=i.provider,o=r.startsWith("0x")?r:b[r],c=(await a.getNetwork()).chainId,s=o?t.from(o).toNumber():c,d=[],{address:l,publicKey:u}=y(e),h=u;let f=await this.previousChange(l,r,n);for(;f;){const e=f,t=S(i,await a.getLogs({address:i.address,topics:[null,`0x000000000000000000000000${l.slice(2)}`],fromBlock:f.toHexString(),toBlock:f.toHexString()}));t.reverse(),f=null;for(const r of t)d.unshift(r),r.previousChange.lt(e)&&(f=r.previousChange)}return{address:l,history:d,controllerKey:h,chainId:s}}wrapDidDocument(r,n,i,a,o,c,s){var l;const u={"@context":["https://www.w3.org/ns/did/v1","https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld"],id:r,verificationMethod:[],authentication:[],assertionMethod:[]};let p=n;const v=[`${r}#controller`];let y=0,w=Number.POSITIVE_INFINITY,b=!1,k=0,D=0;const x={},I={},K={};for(const n of a){if(-1!==c&&n.blockNumber>c){w>n.blockNumber&&(w=n.blockNumber);continue}y<n.blockNumber&&(y=n.blockNumber);const i=n.validTo||t.from(0),a=`${n._eventName}-${n.delegateType||n.name}-${n.delegate||n.value}`;if(i&&i.gte(s)){if(n._eventName===f.DIDDelegateChanged){const e=n;switch(k++,e.delegateType){case"sigAuth":x[a]=`${r}#delegate-${k}`;case"veriKey":I[a]={id:`${r}#delegate-${k}`,type:h.EcdsaSecp256k1RecoveryMethod2020,controller:r,blockchainAccountId:`${e.delegate}@eip155:${o}`}}}else if(n._eventName===f.DIDAttributeChanged){const t=n,i=t.name.match(/^did\/(pub|svc)\/(\w+)(\/(\w+))?(\/(\w+))?$/);if(i){const n=i[2],o=m[i[4]]||i[4],c=i[6];switch(i[1]){case"pub":{k++;const s={id:`${r}#delegate-${k}`,type:`${n}${o}`,controller:r};switch(s.type=g[s.type]||n,c){case null:case void 0:case"hex":s.publicKeyHex=t.value.slice(2);break;case"base64":s.publicKeyBase64=Buffer.from(t.value.slice(2),"hex").toString("base64");break;case"base58":s.publicKeyBase58=e.encode(Buffer.from(t.value.slice(2),"hex"));break;case"pem":s.publicKeyPem=Buffer.from(t.value.slice(2),"hex").toString();break;default:s.value=t.value}I[a]=s,"sigAuth"===i[4]&&(x[a]=s.id);break}case"svc":D++,K[a]={id:`${r}#service-${D}`,type:n,serviceEndpoint:Buffer.from(t.value.slice(2),"hex").toString()}}}}}else if(n._eventName===f.DIDOwnerChanged){if(p=n.owner,"0x0000000000000000000000000000000000000000"===n.owner){b=!0;break}}else n._eventName===f.DIDDelegateChanged||n._eventName===f.DIDAttributeChanged&&n.name.match(/^did\/pub\//)?k++:n._eventName===f.DIDAttributeChanged&&n.name.match(/^did\/svc\//)&&D++,delete x[a],delete I[a],delete K[a]}const S=[{id:`${r}#controller`,type:h.EcdsaSecp256k1RecoveryMethod2020,controller:r,blockchainAccountId:`${p}@eip155:${o}`}];i&&p==n&&(S.push({id:`${r}#controllerKey`,type:h.EcdsaSecp256k1VerificationKey2019,controller:r,publicKeyHex:i}),v.push(`${r}#controllerKey`));const $=d({},u,{verificationMethod:S.concat(Object.values(I)),authentication:v.concat(Object.values(x))});return Object.values(K).length>0&&($.service=Object.values(K)),$.assertionMethod=[...(null==(l=$.verificationMethod)?void 0:l.map(e=>e.id))||[]],b?{didDocument:d({},u,{"@context":"https://www.w3.org/ns/did/v1"}),deactivated:b,versionId:y,nextVersionId:w}:{didDocument:$,deactivated:b,versionId:y,nextVersionId:w}}async resolve(e,r,n,i){const a=r.id.match(l);if(!a)return{didResolutionMetadata:{error:k.invalidDid,message:`Not a valid did:ethr: ${r.id}`},didDocumentMetadata:{},didDocument:null};const o=a[2],c=a[1]?a[1].slice(0,-1):"mainnet";let u=i.blockTag||"latest";if("string"==typeof r.query){const e=s(r.query);u="string"==typeof e.versionId?e.versionId:u;try{u=Number.parseInt(u)}catch(e){u="latest"}}if(!this.contracts[c])return{didResolutionMetadata:{error:k.unknownNetwork,message:`The DID resolver does not have a configuration for network: ${c}`},didDocumentMetadata:{},didDocument:null};let h=t.from(Math.floor((new Date).getTime()/1e3));if("number"==typeof u){const e=await this.getBlockMetadata(u,c);h=t.from(Date.parse(e.isoDate)/1e3)}const{address:f,history:m,controllerKey:g,chainId:p}=await this.changeLog(o,c,"latest");try{const{didDocument:t,deactivated:r,versionId:n,nextVersionId:i}=this.wrapDidDocument(e,f,g,m,p,u,h),a=r?{deactivated:!0}:{};let o={},s={};if(0!==n){const e=await this.getBlockMetadata(n,c);o={versionId:e.height,updated:e.isoDate}}if(i!==Number.POSITIVE_INFINITY){const e=await this.getBlockMetadata(i,c);s={nextVersionId:e.height,nextUpdate:e.isoDate}}return{didDocumentMetadata:d({},a,o,s),didResolutionMetadata:{contentType:"application/did+ld+json"},didDocument:t}}catch(e){return{didResolutionMetadata:{error:k.notFound,message:e.toString()},didDocumentMetadata:{},didDocument:null}}}build(){return{ethr:this.resolve.bind(this)}}}export{k as Errors,K as EthrDidController,u as REGISTRY,m as attrTypes,p as bytes32toString,g as delegateTypes,$ as getResolver,l as identifierMatcher,y as interpretIdentifier,v as stringToBytes32,h as verificationMethodTypes}; | ||
import { Base58 } from '@ethersproject/basex'; | ||
import { BigNumber } from '@ethersproject/bignumber'; | ||
import { ContractFactory } from '@ethersproject/contracts'; | ||
import { JsonRpcProvider, InfuraProvider } from '@ethersproject/providers'; | ||
import DidRegistryContract from 'ethr-did-registry'; | ||
import { getAddress } from '@ethersproject/address'; | ||
import { computeAddress } from '@ethersproject/transactions'; | ||
import * as qs from 'querystring'; | ||
function _extends() { | ||
_extends = Object.assign || function (target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i]; | ||
for (var key in source) { | ||
if (Object.prototype.hasOwnProperty.call(source, key)) { | ||
target[key] = source[key]; | ||
} | ||
} | ||
} | ||
return target; | ||
}; | ||
return _extends.apply(this, arguments); | ||
} | ||
const identifierMatcher = /^(.*)?(0x[0-9a-fA-F]{40}|0x[0-9a-fA-F]{66})$/; | ||
const nullAddress = '0x0000000000000000000000000000000000000000'; | ||
const DEFAULT_REGISTRY_ADDRESS = '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b'; | ||
var verificationMethodTypes; | ||
(function (verificationMethodTypes) { | ||
verificationMethodTypes["EcdsaSecp256k1VerificationKey2019"] = "EcdsaSecp256k1VerificationKey2019"; | ||
verificationMethodTypes["EcdsaSecp256k1RecoveryMethod2020"] = "EcdsaSecp256k1RecoveryMethod2020"; | ||
verificationMethodTypes["Ed25519VerificationKey2018"] = "Ed25519VerificationKey2018"; | ||
verificationMethodTypes["RSAVerificationKey2018"] = "RSAVerificationKey2018"; | ||
verificationMethodTypes["X25519KeyAgreementKey2019"] = "X25519KeyAgreementKey2019"; | ||
})(verificationMethodTypes || (verificationMethodTypes = {})); | ||
var eventNames; | ||
(function (eventNames) { | ||
eventNames["DIDOwnerChanged"] = "DIDOwnerChanged"; | ||
eventNames["DIDAttributeChanged"] = "DIDAttributeChanged"; | ||
eventNames["DIDDelegateChanged"] = "DIDDelegateChanged"; | ||
})(eventNames || (eventNames = {})); | ||
const legacyAttrTypes = { | ||
sigAuth: 'SignatureAuthentication2018', | ||
veriKey: 'VerificationKey2018', | ||
enc: 'KeyAgreementKey2019' | ||
}; | ||
const legacyAlgoMap = { | ||
/**@deprecated */ | ||
Secp256k1VerificationKey2018: verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
/**@deprecated */ | ||
Ed25519SignatureAuthentication2018: verificationMethodTypes.Ed25519VerificationKey2018, | ||
/**@deprecated */ | ||
Secp256k1SignatureAuthentication2018: verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
//keep legacy mapping | ||
RSAVerificationKey2018: verificationMethodTypes.RSAVerificationKey2018, | ||
Ed25519VerificationKey2018: verificationMethodTypes.Ed25519VerificationKey2018, | ||
X25519KeyAgreementKey2019: verificationMethodTypes.X25519KeyAgreementKey2019 | ||
}; | ||
function bytes32toString(input) { | ||
const buff = typeof input === 'string' ? Buffer.from(input.slice(2), 'hex') : Buffer.from(input); | ||
return buff.toString('utf8').replace(/\0+$/, ''); | ||
} | ||
function stringToBytes32(str) { | ||
const buffStr = '0x' + Buffer.from(str).slice(0, 32).toString('hex'); | ||
return buffStr + '0'.repeat(66 - buffStr.length); | ||
} | ||
function interpretIdentifier(identifier) { | ||
let id = identifier; | ||
let network = undefined; | ||
if (id.startsWith('did:ethr')) { | ||
id = id.split('?')[0]; | ||
const components = id.split(':'); | ||
id = components[components.length - 1]; | ||
if (components.length >= 4) { | ||
network = components.splice(2, components.length - 3).join(':'); | ||
} | ||
} | ||
if (id.length > 42) { | ||
return { | ||
address: computeAddress(id), | ||
publicKey: id, | ||
network | ||
}; | ||
} else { | ||
return { | ||
address: getAddress(id), | ||
network | ||
}; // checksum address | ||
} | ||
} | ||
const knownInfuraNetworks = { | ||
mainnet: '0x1', | ||
ropsten: '0x3', | ||
rinkeby: '0x4', | ||
goerli: '0x5', | ||
kovan: '0x2a' | ||
}; | ||
const knownNetworks = _extends({}, knownInfuraNetworks, { | ||
rsk: '0x1e', | ||
'rsk:testnet': '0x1f', | ||
artis_t1: '0x03c401', | ||
artis_s1: '0x03c301', | ||
matic: '0x89', | ||
maticmum: '0x13881' | ||
}); | ||
var Errors; | ||
(function (Errors) { | ||
/** | ||
* The resolver has failed to construct the DID document. | ||
* This can be caused by a network issue, a wrong registry address or malformed logs while parsing the registry history. | ||
* Please inspect the `DIDResolutionMetadata.message` to debug further. | ||
*/ | ||
Errors["notFound"] = "notFound"; | ||
/** | ||
* The resolver does not know how to resolve the given DID. Most likely it is not a `did:ethr`. | ||
*/ | ||
Errors["invalidDid"] = "invalidDid"; | ||
/** | ||
* The resolver is misconfigured or is being asked to resolve a DID anchored on an unknown network | ||
*/ | ||
Errors["unknownNetwork"] = "unknownNetwork"; | ||
})(Errors || (Errors = {})); | ||
function configureNetworksWithInfura(projectId) { | ||
if (!projectId) { | ||
return {}; | ||
} | ||
const networks = [{ | ||
name: 'mainnet', | ||
chainId: '0x1', | ||
provider: new InfuraProvider('homestead', projectId) | ||
}, { | ||
name: 'ropsten', | ||
chainId: '0x3', | ||
provider: new InfuraProvider('ropsten', projectId) | ||
}, { | ||
name: 'rinkeby', | ||
chainId: '0x4', | ||
provider: new InfuraProvider('rinkeby', projectId) | ||
}, { | ||
name: 'goerli', | ||
chainId: '0x5', | ||
provider: new InfuraProvider('goerli', projectId) | ||
}, { | ||
name: 'kovan', | ||
chainId: '0x2a', | ||
provider: new InfuraProvider('kovan', projectId) | ||
}]; | ||
return configureNetworks({ | ||
networks | ||
}); | ||
} | ||
function getContractForNetwork(conf) { | ||
var _conf$web; | ||
let provider = conf.provider || ((_conf$web = conf.web3) == null ? void 0 : _conf$web.currentProvider); | ||
if (!provider) { | ||
if (conf.rpcUrl) { | ||
var _conf$name; | ||
const chainIdRaw = conf.chainId ? conf.chainId : knownNetworks[conf.name || '']; | ||
const chainId = chainIdRaw ? BigNumber.from(chainIdRaw).toNumber() : chainIdRaw; | ||
const networkName = knownInfuraNetworks[conf.name || ''] ? (_conf$name = conf.name) == null ? void 0 : _conf$name.replace('mainnet', 'homestead') : 'any'; | ||
provider = new JsonRpcProvider(conf.rpcUrl, chainId || networkName); | ||
} else { | ||
throw new Error(`invalid_config: No web3 provider could be determined for network ${conf.name || conf.chainId}`); | ||
} | ||
} | ||
const contract = ContractFactory.fromSolidity(DidRegistryContract).attach(conf.registry || DEFAULT_REGISTRY_ADDRESS).connect(provider); | ||
return contract; | ||
} | ||
function configureNetwork(net) { | ||
const networks = {}; | ||
const chainId = net.chainId || knownNetworks[net.name || '']; | ||
if (chainId) { | ||
if (net.name) { | ||
networks[net.name] = getContractForNetwork(net); | ||
} | ||
const id = typeof chainId === 'number' ? `0x${chainId.toString(16)}` : chainId; | ||
networks[id] = getContractForNetwork(net); | ||
} else if (net.provider || net.web3 || net.rpcUrl) { | ||
networks[net.name || ''] = getContractForNetwork(net); | ||
} | ||
return networks; | ||
} | ||
function configureNetworks(conf) { | ||
var _conf$networks; | ||
return _extends({}, configureNetwork(conf), (_conf$networks = conf.networks) == null ? void 0 : _conf$networks.reduce((networks, net) => { | ||
return _extends({}, networks, configureNetwork(net)); | ||
}, {})); | ||
} | ||
/** | ||
* Generates a configuration that maps ethereum network names and chainIDs to the respective ERC1056 contracts deployed on them. | ||
* @returns a record of ERC1056 `Contract` instances | ||
* @param conf configuration options for the resolver. An array of network details. | ||
* Each network entry should contain at least one of `name` or `chainId` AND one of `provider`, `web3`, or `rpcUrl` | ||
* For convenience, you can also specify an `infuraProjectId` which will create a mapping for all the networks supported by https://infura.io. | ||
* @example ```js | ||
* [ | ||
* { name: 'development', registry: '0x9af37603e98e0dc2b855be647c39abe984fc2445', rpcUrl: 'http://127.0.0.1:8545/' }, | ||
* { name: 'goerli', chainId: 5, provider: new InfuraProvider('goerli') }, | ||
* { name: 'rinkeby', provider: new AlchemyProvider('rinkeby') }, | ||
* { name: 'rsk:testnet', chainId: '0x1f', rpcUrl: 'https://public-node.testnet.rsk.co' }, | ||
* ] | ||
* ``` | ||
*/ | ||
function configureResolverWithNetworks(conf = {}) { | ||
const networks = _extends({}, configureNetworksWithInfura(conf.infuraProjectId), configureNetworks(conf)); | ||
if (Object.keys(networks).length === 0) { | ||
throw new Error('invalid_config: Please make sure to have at least one network'); | ||
} | ||
return networks; | ||
} | ||
/** | ||
* A class that can be used to interact with the ERC1056 contract on behalf of a local controller key-pair | ||
*/ | ||
class EthrDidController { | ||
/** | ||
* Creates an EthrDidController instance. | ||
* | ||
* @param identifier - required - a `did:ethr` string or a publicKeyHex or an ethereum address | ||
* @param signer - optional - a Signer that represents the current controller key (owner) of the identifier. If a 'signer' is not provided, then a 'contract' with an attached signer can be used. | ||
* @param contract - optional - a Contract instance representing a ERC1056 contract. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param chainNameOrId - optional - the network name or chainID, defaults to 'mainnet' | ||
* @param provider - optional - a web3 Provider. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param rpcUrl - optional - a JSON-RPC URL that can be used to connect to an ethereum network. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param registry - optional - The ERC1056 registry address. Defaults to '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b'. Only used with 'provider' or 'rpcUrl' | ||
*/ | ||
constructor(identifier, contract, signer, chainNameOrId = 'mainnet', provider, rpcUrl, registry = DEFAULT_REGISTRY_ADDRESS) { | ||
this.contract = void 0; | ||
this.signer = void 0; | ||
this.address = void 0; | ||
this.did = void 0; | ||
// initialize identifier | ||
const { | ||
address, | ||
publicKey, | ||
network | ||
} = interpretIdentifier(identifier); | ||
const net = network || chainNameOrId; // initialize contract connection | ||
if (contract) { | ||
this.contract = contract; | ||
} else if (provider || signer != null && signer.provider || rpcUrl) { | ||
const prov = provider || (signer == null ? void 0 : signer.provider); | ||
this.contract = getContractForNetwork({ | ||
name: net, | ||
provider: prov, | ||
registry, | ||
rpcUrl | ||
}); | ||
} else { | ||
throw new Error(' either a contract instance or a provider or rpcUrl is required to initialize'); | ||
} | ||
this.signer = signer; | ||
this.address = address; | ||
let networkString = net ? `${net}:` : ''; | ||
if (networkString in ['mainnet:', '0x1:']) { | ||
networkString = ''; | ||
} | ||
this.did = publicKey ? `did:ethr:${networkString}${publicKey}` : `did:ethr:${networkString}${address}`; | ||
} | ||
async getOwner(address, blockTag) { | ||
const result = await this.contract.functions.identityOwner(address, { | ||
blockTag | ||
}); | ||
return result[0]; | ||
} | ||
async attachContract(controller) { | ||
const currentOwner = controller ? await controller : await this.getOwner(this.address, 'latest'); | ||
const signer = this.signer ? this.signer : this.contract.provider.getSigner(currentOwner) || this.contract.signer; | ||
return this.contract.connect(signer); | ||
} | ||
async changeOwner(newOwner, options = {}) { | ||
// console.log(`changing owner for ${oldOwner} on registry at ${registryContract.address}`) | ||
const overrides = _extends({ | ||
gasLimit: 123456, | ||
gasPrice: 1000000000 | ||
}, options); | ||
const contract = await this.attachContract(overrides.from); | ||
delete overrides.from; | ||
const ownerChange = await contract.functions.changeOwner(this.address, newOwner, overrides); | ||
return await ownerChange.wait(); | ||
} | ||
async addDelegate(delegateType, delegateAddress, exp, options = {}) { | ||
const overrides = _extends({ | ||
gasLimit: 123456, | ||
gasPrice: 1000000000 | ||
}, options); | ||
const contract = await this.attachContract(overrides.from); | ||
delete overrides.from; | ||
const delegateTypeBytes = stringToBytes32(delegateType); | ||
const addDelegateTx = await contract.functions.addDelegate(this.address, delegateTypeBytes, delegateAddress, exp, overrides); | ||
return await addDelegateTx.wait(); | ||
} | ||
async revokeDelegate(delegateType, delegateAddress, options = {}) { | ||
const overrides = _extends({ | ||
gasLimit: 123456, | ||
gasPrice: 1000000000 | ||
}, options); | ||
delegateType = delegateType.startsWith('0x') ? delegateType : stringToBytes32(delegateType); | ||
const contract = await this.attachContract(overrides.from); | ||
delete overrides.from; | ||
const addDelegateTx = await contract.functions.revokeDelegate(this.address, delegateType, delegateAddress, overrides); | ||
return await addDelegateTx.wait(); | ||
} | ||
async setAttribute(attrName, attrValue, exp, options = {}) { | ||
const overrides = _extends({ | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
controller: undefined | ||
}, options); | ||
attrName = attrName.startsWith('0x') ? attrName : stringToBytes32(attrName); | ||
attrValue = attrValue.startsWith('0x') ? attrValue : '0x' + Buffer.from(attrValue, 'utf-8').toString('hex'); | ||
const contract = await this.attachContract(overrides.from); | ||
delete overrides.from; | ||
const setAttrTx = await contract.functions.setAttribute(this.address, attrName, attrValue, exp, overrides); | ||
return await setAttrTx.wait(); | ||
} | ||
async revokeAttribute(attrName, attrValue, options = {}) { | ||
// console.log(`revoking attribute ${attrName}(${attrValue}) for ${identity}`) | ||
const overrides = _extends({ | ||
gasLimit: 123456, | ||
gasPrice: 1000000000 | ||
}, options); | ||
attrName = attrName.startsWith('0x') ? attrName : stringToBytes32(attrName); | ||
attrValue = attrValue.startsWith('0x') ? attrValue : '0x' + Buffer.from(attrValue, 'utf-8').toString('hex'); | ||
const contract = await this.attachContract(overrides.from); | ||
delete overrides.from; | ||
const revokeAttributeTX = await contract.functions.revokeAttribute(this.address, attrName, attrValue, overrides); | ||
return await revokeAttributeTX.wait(); | ||
} | ||
} | ||
function populateEventMetaClass(logResult, blockNumber) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const result = {}; | ||
if (logResult.eventFragment.inputs.length !== logResult.args.length) { | ||
throw new TypeError('malformed event input. wrong number of arguments'); | ||
} | ||
logResult.eventFragment.inputs.forEach((input, index) => { | ||
let val = logResult.args[index]; | ||
if (typeof val === 'object') { | ||
val = BigNumber.from(val); | ||
} | ||
if (input.type === 'bytes32') { | ||
val = bytes32toString(val); | ||
} | ||
result[input.name] = val; | ||
}); | ||
result._eventName = logResult.name; | ||
result.blockNumber = blockNumber; | ||
return result; | ||
} | ||
function logDecoder(contract, logs) { | ||
const results = logs.map(log => { | ||
const res = contract.interface.parseLog(log); | ||
const event = populateEventMetaClass(res, log.blockNumber); | ||
return event; | ||
}); | ||
return results; | ||
} | ||
function getResolver(options) { | ||
return new EthrDidResolver(options).build(); | ||
} | ||
class EthrDidResolver { | ||
constructor(options) { | ||
this.contracts = void 0; | ||
this.contracts = configureResolverWithNetworks(options); | ||
} | ||
/** | ||
* returns the current owner of a DID (represented by an address or public key) | ||
* | ||
* @param address | ||
*/ | ||
async getOwner(address, networkId, blockTag) { | ||
//TODO: check if address or public key | ||
return new EthrDidController(address, this.contracts[networkId]).getOwner(address, blockTag); | ||
} | ||
/** | ||
* returns the previous change | ||
* | ||
* @param address | ||
*/ | ||
async previousChange(address, networkId, blockTag) { | ||
const result = await this.contracts[networkId].functions.changed(address, { | ||
blockTag | ||
}); // console.log(`last change result: '${BigNumber.from(result['0'])}'`) | ||
return BigNumber.from(result['0']); | ||
} | ||
async getBlockMetadata(blockHeight, networkId) { | ||
const block = await this.contracts[networkId].provider.getBlock(blockHeight); | ||
return { | ||
height: block.number.toString(), | ||
isoDate: new Date(block.timestamp * 1000).toISOString().replace('.000', '') | ||
}; | ||
} | ||
async changeLog(identity, networkId, blockTag = 'latest') { | ||
const contract = this.contracts[networkId]; | ||
const provider = contract.provider; | ||
const hexChainId = networkId.startsWith('0x') ? networkId : knownNetworks[networkId]; //TODO: this can be used to check if the configuration is ok | ||
const chainId = hexChainId ? BigNumber.from(hexChainId).toNumber() : (await provider.getNetwork()).chainId; | ||
const history = []; | ||
const { | ||
address, | ||
publicKey | ||
} = interpretIdentifier(identity); | ||
const controllerKey = publicKey; | ||
let previousChange = await this.previousChange(address, networkId, blockTag); | ||
while (previousChange) { | ||
const blockNumber = previousChange; // console.log(`gigel ${previousChange}`) | ||
const logs = await provider.getLogs({ | ||
address: contract.address, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
topics: [null, `0x000000000000000000000000${address.slice(2)}`], | ||
fromBlock: previousChange.toHexString(), | ||
toBlock: previousChange.toHexString() | ||
}); | ||
const events = logDecoder(contract, logs); | ||
events.reverse(); | ||
previousChange = null; | ||
for (const event of events) { | ||
history.unshift(event); | ||
if (event.previousChange.lt(blockNumber)) { | ||
previousChange = event.previousChange; | ||
} | ||
} | ||
} | ||
return { | ||
address, | ||
history, | ||
controllerKey, | ||
chainId | ||
}; | ||
} | ||
wrapDidDocument(did, address, controllerKey, history, chainId, blockHeight, now) { | ||
var _didDocument$verifica; | ||
const baseDIDDocument = { | ||
'@context': ['https://www.w3.org/ns/did/v1', 'https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld'], | ||
id: did, | ||
verificationMethod: [], | ||
authentication: [], | ||
assertionMethod: [] | ||
}; | ||
let controller = address; | ||
const authentication = [`${did}#controller`]; | ||
let versionId = 0; | ||
let nextVersionId = Number.POSITIVE_INFINITY; | ||
let deactivated = false; | ||
let delegateCount = 0; | ||
let serviceCount = 0; | ||
const auth = {}; | ||
const pks = {}; | ||
const services = {}; | ||
for (const event of history) { | ||
if (blockHeight !== -1 && event.blockNumber > blockHeight) { | ||
if (nextVersionId > event.blockNumber) { | ||
nextVersionId = event.blockNumber; | ||
} | ||
continue; | ||
} else { | ||
if (versionId < event.blockNumber) { | ||
versionId = event.blockNumber; | ||
} | ||
} | ||
const validTo = event.validTo || BigNumber.from(0); | ||
const eventIndex = `${event._eventName}-${event.delegateType || event.name}-${event.delegate || event.value}`; | ||
if (validTo && validTo.gte(now)) { | ||
if (event._eventName === eventNames.DIDDelegateChanged) { | ||
const currentEvent = event; | ||
delegateCount++; | ||
const delegateType = currentEvent.delegateType; //conversion from bytes32 is done in logParser | ||
switch (delegateType) { | ||
case 'sigAuth': | ||
auth[eventIndex] = `${did}#delegate-${delegateCount}`; | ||
// eslint-disable-line no-fallthrough | ||
case 'veriKey': | ||
pks[eventIndex] = { | ||
id: `${did}#delegate-${delegateCount}`, | ||
type: verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020, | ||
controller: did, | ||
blockchainAccountId: `${currentEvent.delegate}@eip155:${chainId}` | ||
}; | ||
break; | ||
} | ||
} else if (event._eventName === eventNames.DIDAttributeChanged) { | ||
const currentEvent = event; | ||
const name = currentEvent.name; //conversion from bytes32 is done in logParser | ||
const match = name.match(/^did\/(pub|svc)\/(\w+)(\/(\w+))?(\/(\w+))?$/); | ||
if (match) { | ||
const section = match[1]; | ||
const algorithm = match[2]; | ||
const type = legacyAttrTypes[match[4]] || match[4]; | ||
const encoding = match[6]; | ||
switch (section) { | ||
case 'pub': | ||
{ | ||
delegateCount++; | ||
const pk = { | ||
id: `${did}#delegate-${delegateCount}`, | ||
type: `${algorithm}${type}`, | ||
controller: did | ||
}; | ||
pk.type = legacyAlgoMap[pk.type] || algorithm; | ||
switch (encoding) { | ||
case null: | ||
case undefined: | ||
case 'hex': | ||
pk.publicKeyHex = currentEvent.value.slice(2); | ||
break; | ||
case 'base64': | ||
pk.publicKeyBase64 = Buffer.from(currentEvent.value.slice(2), 'hex').toString('base64'); | ||
break; | ||
case 'base58': | ||
pk.publicKeyBase58 = Base58.encode(Buffer.from(currentEvent.value.slice(2), 'hex')); | ||
break; | ||
case 'pem': | ||
pk.publicKeyPem = Buffer.from(currentEvent.value.slice(2), 'hex').toString(); | ||
break; | ||
default: | ||
pk.value = currentEvent.value; | ||
} | ||
pks[eventIndex] = pk; | ||
if (match[4] === 'sigAuth') { | ||
auth[eventIndex] = pk.id; | ||
} | ||
break; | ||
} | ||
case 'svc': | ||
serviceCount++; | ||
services[eventIndex] = { | ||
id: `${did}#service-${serviceCount}`, | ||
type: algorithm, | ||
serviceEndpoint: Buffer.from(currentEvent.value.slice(2), 'hex').toString() | ||
}; | ||
break; | ||
} | ||
} | ||
} | ||
} else if (event._eventName === eventNames.DIDOwnerChanged) { | ||
const currentEvent = event; | ||
controller = currentEvent.owner; | ||
if (currentEvent.owner === nullAddress) { | ||
deactivated = true; | ||
break; | ||
} | ||
} else { | ||
if (event._eventName === eventNames.DIDDelegateChanged || event._eventName === eventNames.DIDAttributeChanged && event.name.match(/^did\/pub\//)) { | ||
delegateCount++; | ||
} else if (event._eventName === eventNames.DIDAttributeChanged && event.name.match(/^did\/svc\//)) { | ||
serviceCount++; | ||
} | ||
delete auth[eventIndex]; | ||
delete pks[eventIndex]; | ||
delete services[eventIndex]; | ||
} | ||
} | ||
const publicKeys = [{ | ||
id: `${did}#controller`, | ||
type: verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020, | ||
controller: did, | ||
blockchainAccountId: `${controller}@eip155:${chainId}` | ||
}]; | ||
if (controllerKey && controller == address) { | ||
publicKeys.push({ | ||
id: `${did}#controllerKey`, | ||
type: verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
controller: did, | ||
publicKeyHex: controllerKey | ||
}); | ||
authentication.push(`${did}#controllerKey`); | ||
} | ||
const didDocument = _extends({}, baseDIDDocument, { | ||
verificationMethod: publicKeys.concat(Object.values(pks)), | ||
authentication: authentication.concat(Object.values(auth)) | ||
}); | ||
if (Object.values(services).length > 0) { | ||
didDocument.service = Object.values(services); | ||
} | ||
didDocument.assertionMethod = [...(((_didDocument$verifica = didDocument.verificationMethod) == null ? void 0 : _didDocument$verifica.map(pk => pk.id)) || [])]; | ||
return deactivated ? { | ||
didDocument: _extends({}, baseDIDDocument, { | ||
'@context': 'https://www.w3.org/ns/did/v1' | ||
}), | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
} : { | ||
didDocument, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
}; | ||
} | ||
async resolve(did, parsed, // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_unused, options) { | ||
const fullId = parsed.id.match(identifierMatcher); | ||
if (!fullId) { | ||
return { | ||
didResolutionMetadata: { | ||
error: Errors.invalidDid, | ||
message: `Not a valid did:ethr: ${parsed.id}` | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}; | ||
} | ||
const id = fullId[2]; | ||
const networkId = !fullId[1] ? 'mainnet' : fullId[1].slice(0, -1); | ||
let blockTag = options.blockTag || 'latest'; | ||
if (typeof parsed.query === 'string') { | ||
const qParams = qs.decode(parsed.query); | ||
blockTag = typeof qParams['versionId'] === 'string' ? qParams['versionId'] : blockTag; | ||
try { | ||
blockTag = Number.parseInt(blockTag); | ||
} catch (e) { | ||
blockTag = 'latest'; // invalid versionId parameters are ignored | ||
} | ||
} | ||
if (!this.contracts[networkId]) { | ||
return { | ||
didResolutionMetadata: { | ||
error: Errors.unknownNetwork, | ||
message: `The DID resolver does not have a configuration for network: ${networkId}` | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}; | ||
} | ||
let now = BigNumber.from(Math.floor(new Date().getTime() / 1000)); | ||
if (typeof blockTag === 'number') { | ||
const block = await this.getBlockMetadata(blockTag, networkId); | ||
now = BigNumber.from(Date.parse(block.isoDate) / 1000); | ||
} | ||
const { | ||
address, | ||
history, | ||
controllerKey, | ||
chainId | ||
} = await this.changeLog(id, networkId, 'latest'); | ||
try { | ||
const { | ||
didDocument, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
} = this.wrapDidDocument(did, address, controllerKey, history, chainId, blockTag, now); | ||
const status = deactivated ? { | ||
deactivated: true | ||
} : {}; | ||
let versionMeta = {}; | ||
let versionMetaNext = {}; | ||
if (versionId !== 0) { | ||
const block = await this.getBlockMetadata(versionId, networkId); | ||
versionMeta = { | ||
versionId: block.height, | ||
updated: block.isoDate | ||
}; | ||
} | ||
if (nextVersionId !== Number.POSITIVE_INFINITY) { | ||
const block = await this.getBlockMetadata(nextVersionId, networkId); | ||
versionMetaNext = { | ||
nextVersionId: block.height, | ||
nextUpdate: block.isoDate | ||
}; | ||
} | ||
return { | ||
didDocumentMetadata: _extends({}, status, versionMeta, versionMetaNext), | ||
didResolutionMetadata: { | ||
contentType: 'application/did+ld+json' | ||
}, | ||
didDocument | ||
}; | ||
} catch (e) { | ||
return { | ||
didResolutionMetadata: { | ||
error: Errors.notFound, | ||
message: e.toString() // This is not in spec, nut may be helpful | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}; | ||
} | ||
} | ||
build() { | ||
return { | ||
ethr: this.resolve.bind(this) | ||
}; | ||
} | ||
} | ||
export { Errors, EthrDidController, DEFAULT_REGISTRY_ADDRESS as REGISTRY, legacyAttrTypes as attrTypes, bytes32toString, legacyAlgoMap as delegateTypes, getResolver, identifierMatcher, interpretIdentifier, stringToBytes32, verificationMethodTypes }; | ||
//# sourceMappingURL=index.modern.js.map |
1148
lib/index.umd.js
@@ -1,2 +0,1148 @@ | ||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@ethersproject/basex"),require("@ethersproject/bignumber"),require("@ethersproject/contracts"),require("@ethersproject/providers"),require("ethr-did-registry"),require("@ethersproject/address"),require("@ethersproject/transactions"),require("querystring")):"function"==typeof define&&define.amd?define(["exports","@ethersproject/basex","@ethersproject/bignumber","@ethersproject/contracts","@ethersproject/providers","ethr-did-registry","@ethersproject/address","@ethersproject/transactions","querystring"],t):t((e||self).ethrDidResolver={},e.basex,e.bignumber,e.contracts,e.providers,e.ethrDidRegistry,e.address,e.transactions,e.querystring)}(this,function(e,t,r,n,i,o,c,s,a){function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var u=d(o);const h=/^(.*)?(0x[0-9a-fA-F]{40}|0x[0-9a-fA-F]{66})$/,l="0xdca7ef03e98e0dc2b855be647c39abe984fcf21b";var f,v;e.verificationMethodTypes=void 0,(f=e.verificationMethodTypes||(e.verificationMethodTypes={})).EcdsaSecp256k1VerificationKey2019="EcdsaSecp256k1VerificationKey2019",f.EcdsaSecp256k1RecoveryMethod2020="EcdsaSecp256k1RecoveryMethod2020",f.Ed25519VerificationKey2018="Ed25519VerificationKey2018",f.RSAVerificationKey2018="RSAVerificationKey2018",f.X25519KeyAgreementKey2019="X25519KeyAgreementKey2019",function(e){e.DIDOwnerChanged="DIDOwnerChanged",e.DIDAttributeChanged="DIDAttributeChanged",e.DIDDelegateChanged="DIDDelegateChanged"}(v||(v={}));const m={sigAuth:"SignatureAuthentication2018",veriKey:"VerificationKey2018",enc:"KeyAgreementKey2019"},g={Secp256k1VerificationKey2018:e.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019,Ed25519SignatureAuthentication2018:e.verificationMethodTypes.Ed25519VerificationKey2018,Secp256k1SignatureAuthentication2018:e.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019,RSAVerificationKey2018:e.verificationMethodTypes.RSAVerificationKey2018,Ed25519VerificationKey2018:e.verificationMethodTypes.Ed25519VerificationKey2018,X25519KeyAgreementKey2019:e.verificationMethodTypes.X25519KeyAgreementKey2019};function p(e){return("string"==typeof e?Buffer.from(e.slice(2),"hex"):Buffer.from(e)).toString("utf8").replace(/\0+$/,"")}function y(e){const t="0x"+Buffer.from(e).slice(0,32).toString("hex");return t+"0".repeat(66-t.length)}function b(e){let t,r=e;if(r.startsWith("did:ethr")){r=r.split("?")[0];const e=r.split(":");r=e[e.length-1],e.length>=4&&(t=e.splice(2,e.length-3).join(":"))}return r.length>42?{address:s.computeAddress(r),publicKey:r,network:t}:{address:c.getAddress(r),network:t}}const w={mainnet:"0x1",ropsten:"0x3",rinkeby:"0x4",goerli:"0x5",kovan:"0x2a"},k={...w,rsk:"0x1e","rsk:testnet":"0x1f",artis_t1:"0x03c401",artis_s1:"0x03c301",matic:"0x89",maticmum:"0x13881"};var D;function P(e){var t;let o=e.provider||(null==(t=e.web3)?void 0:t.currentProvider);if(!o){if(!e.rpcUrl)throw new Error(`invalid_config: No web3 provider could be determined for network ${e.name||e.chainId}`);{var c;const t=e.chainId?e.chainId:k[e.name||""],n=t?r.BigNumber.from(t).toNumber():t,s=w[e.name||""]?null==(c=e.name)?void 0:c.replace("mainnet","homestead"):"any";o=new i.JsonRpcProvider(e.rpcUrl,n||s)}}return n.ContractFactory.fromSolidity(u.default).attach(e.registry||l).connect(o)}function x(e){const t={},r=e.chainId||k[e.name||""];return r?(e.name&&(t[e.name]=P(e)),t["number"==typeof r?`0x${r.toString(16)}`:r]=P(e)):(e.provider||e.web3||e.rpcUrl)&&(t[e.name||""]=P(e)),t}function I(e){var t;return{...x(e),...null==(t=e.networks)?void 0:t.reduce((e,t)=>({...e,...x(t)}),{})}}e.Errors=void 0,(D=e.Errors||(e.Errors={})).notFound="notFound",D.invalidDid="invalidDid",D.unknownNetwork="unknownNetwork";class K{constructor(e,t,r,n="mainnet",i,o,c=l){const{address:s,publicKey:a,network:d}=b(e),u=d||n;if(t)this.contract=t;else{if(!(i||null!=r&&r.provider||o))throw new Error(" either a contract instance or a provider or rpcUrl is required to initialize");this.contract=P({name:u,provider:i||(null==r?void 0:r.provider),registry:c,rpcUrl:o})}this.signer=r,this.address=s;let h=u?`${u}:`:"";h in["mainnet:","0x1:"]&&(h=""),this.did=a?`did:ethr:${h}${a}`:`did:ethr:${h}${s}`}getOwner(e,t){try{return Promise.resolve(this.contract.functions.identityOwner(e,{blockTag:t})).then(function(e){return e[0]})}catch(e){return Promise.reject(e)}}attachContract(e){try{const t=this;return Promise.resolve(e||t.getOwner(t.address,"latest")).then(function(e){const r=t.signer?t.signer:t.contract.provider.getSigner(e)||t.contract.signer;return t.contract.connect(r)})}catch(e){return Promise.reject(e)}}changeOwner(e,t={}){try{const r=this,n={gasLimit:123456,gasPrice:1e9,...t};return Promise.resolve(r.attachContract(n.from)).then(function(t){return delete n.from,Promise.resolve(t.functions.changeOwner(r.address,e,n)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}addDelegate(e,t,r,n={}){try{const i=this,o={gasLimit:123456,gasPrice:1e9,...n};return Promise.resolve(i.attachContract(o.from)).then(function(n){delete o.from;const c=y(e);return Promise.resolve(n.functions.addDelegate(i.address,c,t,r,o)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}revokeDelegate(e,t,r={}){try{const n=this,i={gasLimit:123456,gasPrice:1e9,...r};return e=e.startsWith("0x")?e:y(e),Promise.resolve(n.attachContract(i.from)).then(function(r){return delete i.from,Promise.resolve(r.functions.revokeDelegate(n.address,e,t,i)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}setAttribute(e,t,r,n={}){try{const i=this,o={gasLimit:123456,gasPrice:1e9,controller:void 0,...n};return e=e.startsWith("0x")?e:y(e),t=t.startsWith("0x")?t:"0x"+Buffer.from(t,"utf-8").toString("hex"),Promise.resolve(i.attachContract(o.from)).then(function(n){return delete o.from,Promise.resolve(n.functions.setAttribute(i.address,e,t,r,o)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}revokeAttribute(e,t,r={}){try{const n=this,i={gasLimit:123456,gasPrice:1e9,...r};return e=e.startsWith("0x")?e:y(e),t=t.startsWith("0x")?t:"0x"+Buffer.from(t,"utf-8").toString("hex"),Promise.resolve(n.attachContract(i.from)).then(function(r){return delete i.from,Promise.resolve(r.functions.revokeAttribute(n.address,e,t,i)).then(function(e){return Promise.resolve(e.wait())})})}catch(e){return Promise.reject(e)}}}function S(e,t,r){if(!e.s){if(r instanceof N){if(!r.s)return void(r.o=S.bind(null,e,t));1&t&&(t=r.s),r=r.v}if(r&&r.then)return void r.then(S.bind(null,e,t),S.bind(null,e,2));e.s=t,e.v=r;const n=e.o;n&&n(e)}}const N=function(){function e(){}return e.prototype.then=function(t,r){const n=new e,i=this.s;if(i){const e=1&i?t:r;if(e){try{S(n,1,e(this.v))}catch(e){S(n,2,e)}return n}return this}return this.o=function(e){try{const i=e.v;1&e.s?S(n,1,t?t(i):i):r?S(n,1,r(i)):S(n,2,i)}catch(e){S(n,2,e)}},n},e}();function j(e){return e instanceof N&&1&e.s}class M{constructor(e){this.contracts=function(e={}){const t={...(r=e.infuraProjectId,r?I({networks:[{name:"mainnet",chainId:"0x1",provider:new i.InfuraProvider("homestead",r)},{name:"ropsten",chainId:"0x3",provider:new i.InfuraProvider("ropsten",r)},{name:"rinkeby",chainId:"0x4",provider:new i.InfuraProvider("rinkeby",r)},{name:"goerli",chainId:"0x5",provider:new i.InfuraProvider("goerli",r)},{name:"kovan",chainId:"0x2a",provider:new i.InfuraProvider("kovan",r)}]}):{}),...I(e)};var r;if(0===Object.keys(t).length)throw new Error("invalid_config: Please make sure to have at least one network");return t}(e)}getOwner(e,t,r){try{return Promise.resolve(new K(e,this.contracts[t]).getOwner(e,r))}catch(e){return Promise.reject(e)}}previousChange(e,t,n){try{return Promise.resolve(this.contracts[t].functions.changed(e,{blockTag:n})).then(function(e){return r.BigNumber.from(e[0])})}catch(e){return Promise.reject(e)}}getBlockMetadata(e,t){try{return Promise.resolve(this.contracts[t].provider.getBlock(e)).then(function(e){return{height:e.number.toString(),isoDate:new Date(1e3*e.timestamp).toISOString().replace(".000","")}})}catch(e){return Promise.reject(e)}}changeLog(e,t,n="latest"){try{const i=this,o=i.contracts[t],c=o.provider,s=t.startsWith("0x")?t:k[t];return Promise.resolve(c.getNetwork()).then(function(a){const d=a.chainId,u=s?r.BigNumber.from(s).toNumber():d,h=[],{address:l,publicKey:f}=b(e),v=f;return Promise.resolve(i.previousChange(l,t,n)).then(function(e){function t(){return{address:l,history:h,controllerKey:v,chainId:u}}const n=function(e,t,r){for(var n;;){var i=e();if(j(i)&&(i=i.v),!i)return o;if(i.then){n=0;break}var o=r();if(o&&o.then){if(!j(o)){n=1;break}o=o.s}}var c=new N,s=S.bind(null,c,2);return(0===n?i.then(d):1===n?o.then(a):(void 0).then(function(){(i=e())?i.then?i.then(d).then(void 0,s):d(i):S(c,1,o)})).then(void 0,s),c;function a(t){o=t;do{if(!(i=e())||j(i)&&!i.v)return void S(c,1,o);if(i.then)return void i.then(d).then(void 0,s);j(o=r())&&(o=o.v)}while(!o||!o.then);o.then(a).then(void 0,s)}function d(e){e?(o=r())&&o.then?o.then(a).then(void 0,s):a(o):S(c,1,o)}}(function(){return!!e},0,function(){const t=e;return Promise.resolve(c.getLogs({address:o.address,topics:[null,`0x000000000000000000000000${l.slice(2)}`],fromBlock:e.toHexString(),toBlock:e.toHexString()})).then(function(n){const i=function(e,t){return t.map(t=>function(e,t){const n={};if(e.eventFragment.inputs.length!==e.args.length)throw new TypeError("malformed event input. wrong number of arguments");return e.eventFragment.inputs.forEach((t,i)=>{let o=e.args[i];"object"==typeof o&&(o=r.BigNumber.from(o)),"bytes32"===t.type&&(o=p(o)),n[t.name]=o}),n._eventName=e.name,n.blockNumber=t,n}(e.interface.parseLog(t),t.blockNumber))}(o,n);i.reverse(),e=null;for(const r of i)h.unshift(r),r.previousChange.lt(t)&&(e=r.previousChange)})});return n&&n.then?n.then(t):t()})})}catch(e){return Promise.reject(e)}}wrapDidDocument(n,i,o,c,s,a,d){var u;const h={"@context":["https://www.w3.org/ns/did/v1","https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld"],id:n,verificationMethod:[],authentication:[],assertionMethod:[]};let l=i;const f=[`${n}#controller`];let p=0,y=Number.POSITIVE_INFINITY,b=!1,w=0,k=0;const D={},P={},x={};for(const i of c){if(-1!==a&&i.blockNumber>a){y>i.blockNumber&&(y=i.blockNumber);continue}p<i.blockNumber&&(p=i.blockNumber);const o=i.validTo||r.BigNumber.from(0),c=`${i._eventName}-${i.delegateType||i.name}-${i.delegate||i.value}`;if(o&&o.gte(d)){if(i._eventName===v.DIDDelegateChanged){const t=i;switch(w++,t.delegateType){case"sigAuth":D[c]=`${n}#delegate-${w}`;case"veriKey":P[c]={id:`${n}#delegate-${w}`,type:e.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020,controller:n,blockchainAccountId:`${t.delegate}@eip155:${s}`}}}else if(i._eventName===v.DIDAttributeChanged){const e=i,r=e.name.match(/^did\/(pub|svc)\/(\w+)(\/(\w+))?(\/(\w+))?$/);if(r){const i=r[2],o=m[r[4]]||r[4],s=r[6];switch(r[1]){case"pub":{w++;const a={id:`${n}#delegate-${w}`,type:`${i}${o}`,controller:n};switch(a.type=g[a.type]||i,s){case null:case void 0:case"hex":a.publicKeyHex=e.value.slice(2);break;case"base64":a.publicKeyBase64=Buffer.from(e.value.slice(2),"hex").toString("base64");break;case"base58":a.publicKeyBase58=t.Base58.encode(Buffer.from(e.value.slice(2),"hex"));break;case"pem":a.publicKeyPem=Buffer.from(e.value.slice(2),"hex").toString();break;default:a.value=e.value}P[c]=a,"sigAuth"===r[4]&&(D[c]=a.id);break}case"svc":k++,x[c]={id:`${n}#service-${k}`,type:i,serviceEndpoint:Buffer.from(e.value.slice(2),"hex").toString()}}}}}else if(i._eventName===v.DIDOwnerChanged){if(l=i.owner,"0x0000000000000000000000000000000000000000"===i.owner){b=!0;break}}else i._eventName===v.DIDDelegateChanged||i._eventName===v.DIDAttributeChanged&&i.name.match(/^did\/pub\//)?w++:i._eventName===v.DIDAttributeChanged&&i.name.match(/^did\/svc\//)&&k++,delete D[c],delete P[c],delete x[c]}const I=[{id:`${n}#controller`,type:e.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020,controller:n,blockchainAccountId:`${l}@eip155:${s}`}];o&&l==i&&(I.push({id:`${n}#controllerKey`,type:e.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019,controller:n,publicKeyHex:o}),f.push(`${n}#controllerKey`));const K={...h,verificationMethod:I.concat(Object.values(P)),authentication:f.concat(Object.values(D))};return Object.values(x).length>0&&(K.service=Object.values(x)),K.assertionMethod=[...(null==(u=K.verificationMethod)?void 0:u.map(e=>e.id))||[]],b?{didDocument:{...h,"@context":"https://www.w3.org/ns/did/v1"},deactivated:b,versionId:p,nextVersionId:y}:{didDocument:K,deactivated:b,versionId:p,nextVersionId:y}}resolve(t,n,i,o){try{const i=this;function c(){return Promise.resolve(i.changeLog(d,u,"latest")).then(function({address:r,history:n,controllerKey:o,chainId:c}){return function(e,s){try{var a=function(){function e(){function e(){return{didDocumentMetadata:{...v,...m,...g},didResolutionMetadata:{contentType:"application/did+ld+json"},didDocument:s}}const t=function(){if(h!==Number.POSITIVE_INFINITY)return Promise.resolve(i.getBlockMetadata(h,u)).then(function(e){g={nextVersionId:e.height,nextUpdate:e.isoDate}})}();return t&&t.then?t.then(e):e()}const{didDocument:s,deactivated:a,versionId:d,nextVersionId:h}=i.wrapDidDocument(t,r,o,n,c,l,f),v=a?{deactivated:!0}:{};let m={},g={};const p=function(){if(0!==d)return Promise.resolve(i.getBlockMetadata(d,u)).then(function(e){m={versionId:e.height,updated:e.isoDate}})}();return p&&p.then?p.then(e):e()}()}catch(e){return s(e)}return a&&a.then?a.then(void 0,s):a}(0,function(t){return{didResolutionMetadata:{error:e.Errors.notFound,message:t.toString()},didDocumentMetadata:{},didDocument:null}})})}const s=n.id.match(h);if(!s)return Promise.resolve({didResolutionMetadata:{error:e.Errors.invalidDid,message:`Not a valid did:ethr: ${n.id}`},didDocumentMetadata:{},didDocument:null});const d=s[2],u=s[1]?s[1].slice(0,-1):"mainnet";let l=o.blockTag||"latest";if("string"==typeof n.query){const e=a.decode(n.query);l="string"==typeof e.versionId?e.versionId:l;try{l=Number.parseInt(l)}catch(e){l="latest"}}if(!i.contracts[u])return Promise.resolve({didResolutionMetadata:{error:e.Errors.unknownNetwork,message:`The DID resolver does not have a configuration for network: ${u}`},didDocumentMetadata:{},didDocument:null});let f=r.BigNumber.from(Math.floor((new Date).getTime()/1e3));const v=function(){if("number"==typeof l)return Promise.resolve(i.getBlockMetadata(l,u)).then(function(e){f=r.BigNumber.from(Date.parse(e.isoDate)/1e3)})}();return Promise.resolve(v&&v.then?v.then(c):c())}catch(e){return Promise.reject(e)}}build(){return{ethr:this.resolve.bind(this)}}}e.EthrDidController=K,e.REGISTRY=l,e.attrTypes=m,e.bytes32toString=p,e.delegateTypes=g,e.getResolver=function(e){return new M(e).build()},e.identifierMatcher=h,e.interpretIdentifier=b,e.stringToBytes32=y}); | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@ethersproject/basex'), require('@ethersproject/bignumber'), require('@ethersproject/contracts'), require('@ethersproject/providers'), require('ethr-did-registry'), require('@ethersproject/address'), require('@ethersproject/transactions'), require('querystring')) : | ||
typeof define === 'function' && define.amd ? define(['exports', '@ethersproject/basex', '@ethersproject/bignumber', '@ethersproject/contracts', '@ethersproject/providers', 'ethr-did-registry', '@ethersproject/address', '@ethersproject/transactions', 'querystring'], factory) : | ||
(global = global || self, factory(global.ethrDidResolver = {}, global.basex, global.bignumber, global.contracts, global.providers, global.ethrDidRegistry, global.address, global.transactions, global.querystring)); | ||
}(this, (function (exports, basex, bignumber, contracts, providers, DidRegistryContract, address, transactions, qs) { | ||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } | ||
function _interopNamespace(e) { | ||
if (e && e.__esModule) return e; | ||
var n = Object.create(null); | ||
if (e) { | ||
Object.keys(e).forEach(function (k) { | ||
if (k !== 'default') { | ||
var d = Object.getOwnPropertyDescriptor(e, k); | ||
Object.defineProperty(n, k, d.get ? d : { | ||
enumerable: true, | ||
get: function () { | ||
return e[k]; | ||
} | ||
}); | ||
} | ||
}); | ||
} | ||
n['default'] = e; | ||
return n; | ||
} | ||
var DidRegistryContract__default = /*#__PURE__*/_interopDefaultLegacy(DidRegistryContract); | ||
var qs__namespace = /*#__PURE__*/_interopNamespace(qs); | ||
const identifierMatcher = /^(.*)?(0x[0-9a-fA-F]{40}|0x[0-9a-fA-F]{66})$/; | ||
const nullAddress = '0x0000000000000000000000000000000000000000'; | ||
const DEFAULT_REGISTRY_ADDRESS = '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b'; | ||
exports.verificationMethodTypes = void 0; | ||
(function (verificationMethodTypes) { | ||
verificationMethodTypes["EcdsaSecp256k1VerificationKey2019"] = "EcdsaSecp256k1VerificationKey2019"; | ||
verificationMethodTypes["EcdsaSecp256k1RecoveryMethod2020"] = "EcdsaSecp256k1RecoveryMethod2020"; | ||
verificationMethodTypes["Ed25519VerificationKey2018"] = "Ed25519VerificationKey2018"; | ||
verificationMethodTypes["RSAVerificationKey2018"] = "RSAVerificationKey2018"; | ||
verificationMethodTypes["X25519KeyAgreementKey2019"] = "X25519KeyAgreementKey2019"; | ||
})(exports.verificationMethodTypes || (exports.verificationMethodTypes = {})); | ||
var eventNames; | ||
(function (eventNames) { | ||
eventNames["DIDOwnerChanged"] = "DIDOwnerChanged"; | ||
eventNames["DIDAttributeChanged"] = "DIDAttributeChanged"; | ||
eventNames["DIDDelegateChanged"] = "DIDDelegateChanged"; | ||
})(eventNames || (eventNames = {})); | ||
const legacyAttrTypes = { | ||
sigAuth: 'SignatureAuthentication2018', | ||
veriKey: 'VerificationKey2018', | ||
enc: 'KeyAgreementKey2019' | ||
}; | ||
const legacyAlgoMap = { | ||
/**@deprecated */ | ||
Secp256k1VerificationKey2018: exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
/**@deprecated */ | ||
Ed25519SignatureAuthentication2018: exports.verificationMethodTypes.Ed25519VerificationKey2018, | ||
/**@deprecated */ | ||
Secp256k1SignatureAuthentication2018: exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
//keep legacy mapping | ||
RSAVerificationKey2018: exports.verificationMethodTypes.RSAVerificationKey2018, | ||
Ed25519VerificationKey2018: exports.verificationMethodTypes.Ed25519VerificationKey2018, | ||
X25519KeyAgreementKey2019: exports.verificationMethodTypes.X25519KeyAgreementKey2019 | ||
}; | ||
function bytes32toString(input) { | ||
const buff = typeof input === 'string' ? Buffer.from(input.slice(2), 'hex') : Buffer.from(input); | ||
return buff.toString('utf8').replace(/\0+$/, ''); | ||
} | ||
function stringToBytes32(str) { | ||
const buffStr = '0x' + Buffer.from(str).slice(0, 32).toString('hex'); | ||
return buffStr + '0'.repeat(66 - buffStr.length); | ||
} | ||
function interpretIdentifier(identifier) { | ||
let id = identifier; | ||
let network = undefined; | ||
if (id.startsWith('did:ethr')) { | ||
id = id.split('?')[0]; | ||
const components = id.split(':'); | ||
id = components[components.length - 1]; | ||
if (components.length >= 4) { | ||
network = components.splice(2, components.length - 3).join(':'); | ||
} | ||
} | ||
if (id.length > 42) { | ||
return { | ||
address: transactions.computeAddress(id), | ||
publicKey: id, | ||
network | ||
}; | ||
} else { | ||
return { | ||
address: address.getAddress(id), | ||
network | ||
}; // checksum address | ||
} | ||
} | ||
const knownInfuraNetworks = { | ||
mainnet: '0x1', | ||
ropsten: '0x3', | ||
rinkeby: '0x4', | ||
goerli: '0x5', | ||
kovan: '0x2a' | ||
}; | ||
const knownNetworks = { ...knownInfuraNetworks, | ||
rsk: '0x1e', | ||
'rsk:testnet': '0x1f', | ||
artis_t1: '0x03c401', | ||
artis_s1: '0x03c301', | ||
matic: '0x89', | ||
maticmum: '0x13881' | ||
}; | ||
exports.Errors = void 0; | ||
(function (Errors) { | ||
/** | ||
* The resolver has failed to construct the DID document. | ||
* This can be caused by a network issue, a wrong registry address or malformed logs while parsing the registry history. | ||
* Please inspect the `DIDResolutionMetadata.message` to debug further. | ||
*/ | ||
Errors["notFound"] = "notFound"; | ||
/** | ||
* The resolver does not know how to resolve the given DID. Most likely it is not a `did:ethr`. | ||
*/ | ||
Errors["invalidDid"] = "invalidDid"; | ||
/** | ||
* The resolver is misconfigured or is being asked to resolve a DID anchored on an unknown network | ||
*/ | ||
Errors["unknownNetwork"] = "unknownNetwork"; | ||
})(exports.Errors || (exports.Errors = {})); | ||
function configureNetworksWithInfura(projectId) { | ||
if (!projectId) { | ||
return {}; | ||
} | ||
const networks = [{ | ||
name: 'mainnet', | ||
chainId: '0x1', | ||
provider: new providers.InfuraProvider('homestead', projectId) | ||
}, { | ||
name: 'ropsten', | ||
chainId: '0x3', | ||
provider: new providers.InfuraProvider('ropsten', projectId) | ||
}, { | ||
name: 'rinkeby', | ||
chainId: '0x4', | ||
provider: new providers.InfuraProvider('rinkeby', projectId) | ||
}, { | ||
name: 'goerli', | ||
chainId: '0x5', | ||
provider: new providers.InfuraProvider('goerli', projectId) | ||
}, { | ||
name: 'kovan', | ||
chainId: '0x2a', | ||
provider: new providers.InfuraProvider('kovan', projectId) | ||
}]; | ||
return configureNetworks({ | ||
networks | ||
}); | ||
} | ||
function getContractForNetwork(conf) { | ||
var _conf$web; | ||
let provider = conf.provider || ((_conf$web = conf.web3) == null ? void 0 : _conf$web.currentProvider); | ||
if (!provider) { | ||
if (conf.rpcUrl) { | ||
var _conf$name; | ||
const chainIdRaw = conf.chainId ? conf.chainId : knownNetworks[conf.name || '']; | ||
const chainId = chainIdRaw ? bignumber.BigNumber.from(chainIdRaw).toNumber() : chainIdRaw; | ||
const networkName = knownInfuraNetworks[conf.name || ''] ? (_conf$name = conf.name) == null ? void 0 : _conf$name.replace('mainnet', 'homestead') : 'any'; | ||
provider = new providers.JsonRpcProvider(conf.rpcUrl, chainId || networkName); | ||
} else { | ||
throw new Error(`invalid_config: No web3 provider could be determined for network ${conf.name || conf.chainId}`); | ||
} | ||
} | ||
const contract = contracts.ContractFactory.fromSolidity(DidRegistryContract__default['default']).attach(conf.registry || DEFAULT_REGISTRY_ADDRESS).connect(provider); | ||
return contract; | ||
} | ||
function configureNetwork(net) { | ||
const networks = {}; | ||
const chainId = net.chainId || knownNetworks[net.name || '']; | ||
if (chainId) { | ||
if (net.name) { | ||
networks[net.name] = getContractForNetwork(net); | ||
} | ||
const id = typeof chainId === 'number' ? `0x${chainId.toString(16)}` : chainId; | ||
networks[id] = getContractForNetwork(net); | ||
} else if (net.provider || net.web3 || net.rpcUrl) { | ||
networks[net.name || ''] = getContractForNetwork(net); | ||
} | ||
return networks; | ||
} | ||
function configureNetworks(conf) { | ||
var _conf$networks; | ||
return { ...configureNetwork(conf), | ||
...((_conf$networks = conf.networks) == null ? void 0 : _conf$networks.reduce((networks, net) => { | ||
return { ...networks, | ||
...configureNetwork(net) | ||
}; | ||
}, {})) | ||
}; | ||
} | ||
/** | ||
* Generates a configuration that maps ethereum network names and chainIDs to the respective ERC1056 contracts deployed on them. | ||
* @returns a record of ERC1056 `Contract` instances | ||
* @param conf configuration options for the resolver. An array of network details. | ||
* Each network entry should contain at least one of `name` or `chainId` AND one of `provider`, `web3`, or `rpcUrl` | ||
* For convenience, you can also specify an `infuraProjectId` which will create a mapping for all the networks supported by https://infura.io. | ||
* @example ```js | ||
* [ | ||
* { name: 'development', registry: '0x9af37603e98e0dc2b855be647c39abe984fc2445', rpcUrl: 'http://127.0.0.1:8545/' }, | ||
* { name: 'goerli', chainId: 5, provider: new InfuraProvider('goerli') }, | ||
* { name: 'rinkeby', provider: new AlchemyProvider('rinkeby') }, | ||
* { name: 'rsk:testnet', chainId: '0x1f', rpcUrl: 'https://public-node.testnet.rsk.co' }, | ||
* ] | ||
* ``` | ||
*/ | ||
function configureResolverWithNetworks(conf = {}) { | ||
const networks = { ...configureNetworksWithInfura(conf.infuraProjectId), | ||
...configureNetworks(conf) | ||
}; | ||
if (Object.keys(networks).length === 0) { | ||
throw new Error('invalid_config: Please make sure to have at least one network'); | ||
} | ||
return networks; | ||
} | ||
/** | ||
* A class that can be used to interact with the ERC1056 contract on behalf of a local controller key-pair | ||
*/ | ||
class EthrDidController { | ||
/** | ||
* Creates an EthrDidController instance. | ||
* | ||
* @param identifier - required - a `did:ethr` string or a publicKeyHex or an ethereum address | ||
* @param signer - optional - a Signer that represents the current controller key (owner) of the identifier. If a 'signer' is not provided, then a 'contract' with an attached signer can be used. | ||
* @param contract - optional - a Contract instance representing a ERC1056 contract. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param chainNameOrId - optional - the network name or chainID, defaults to 'mainnet' | ||
* @param provider - optional - a web3 Provider. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param rpcUrl - optional - a JSON-RPC URL that can be used to connect to an ethereum network. At least one of `contract`, `provider`, or `rpcUrl` is required | ||
* @param registry - optional - The ERC1056 registry address. Defaults to '0xdca7ef03e98e0dc2b855be647c39abe984fcf21b'. Only used with 'provider' or 'rpcUrl' | ||
*/ | ||
constructor(identifier, contract, signer, chainNameOrId = 'mainnet', provider, rpcUrl, registry = DEFAULT_REGISTRY_ADDRESS) { | ||
this.contract = void 0; | ||
this.signer = void 0; | ||
this.address = void 0; | ||
this.did = void 0; | ||
// initialize identifier | ||
const { | ||
address, | ||
publicKey, | ||
network | ||
} = interpretIdentifier(identifier); | ||
const net = network || chainNameOrId; // initialize contract connection | ||
if (contract) { | ||
this.contract = contract; | ||
} else if (provider || signer != null && signer.provider || rpcUrl) { | ||
const prov = provider || (signer == null ? void 0 : signer.provider); | ||
this.contract = getContractForNetwork({ | ||
name: net, | ||
provider: prov, | ||
registry, | ||
rpcUrl | ||
}); | ||
} else { | ||
throw new Error(' either a contract instance or a provider or rpcUrl is required to initialize'); | ||
} | ||
this.signer = signer; | ||
this.address = address; | ||
let networkString = net ? `${net}:` : ''; | ||
if (networkString in ['mainnet:', '0x1:']) { | ||
networkString = ''; | ||
} | ||
this.did = publicKey ? `did:ethr:${networkString}${publicKey}` : `did:ethr:${networkString}${address}`; | ||
} | ||
getOwner(address, blockTag) { | ||
try { | ||
const _this = this; | ||
return Promise.resolve(_this.contract.functions.identityOwner(address, { | ||
blockTag | ||
})).then(function (result) { | ||
return result[0]; | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
attachContract(controller) { | ||
try { | ||
const _this2 = this; | ||
return Promise.resolve(controller ? controller : _this2.getOwner(_this2.address, 'latest')).then(function (currentOwner) { | ||
const signer = _this2.signer ? _this2.signer : _this2.contract.provider.getSigner(currentOwner) || _this2.contract.signer; | ||
return _this2.contract.connect(signer); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
changeOwner(newOwner, options = {}) { | ||
try { | ||
const _this3 = this; | ||
// console.log(`changing owner for ${oldOwner} on registry at ${registryContract.address}`) | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
return Promise.resolve(_this3.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.changeOwner(_this3.address, newOwner, overrides)).then(function (ownerChange) { | ||
return Promise.resolve(ownerChange.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
addDelegate(delegateType, delegateAddress, exp, options = {}) { | ||
try { | ||
const _this4 = this; | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
return Promise.resolve(_this4.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
const delegateTypeBytes = stringToBytes32(delegateType); | ||
return Promise.resolve(contract.functions.addDelegate(_this4.address, delegateTypeBytes, delegateAddress, exp, overrides)).then(function (addDelegateTx) { | ||
addDelegateTx; | ||
return Promise.resolve(addDelegateTx.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
revokeDelegate(delegateType, delegateAddress, options = {}) { | ||
try { | ||
const _this5 = this; | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
delegateType = delegateType.startsWith('0x') ? delegateType : stringToBytes32(delegateType); | ||
return Promise.resolve(_this5.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.revokeDelegate(_this5.address, delegateType, delegateAddress, overrides)).then(function (addDelegateTx) { | ||
return Promise.resolve(addDelegateTx.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
setAttribute(attrName, attrValue, exp, options = {}) { | ||
try { | ||
const _this6 = this; | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
controller: undefined, | ||
...options | ||
}; | ||
attrName = attrName.startsWith('0x') ? attrName : stringToBytes32(attrName); | ||
attrValue = attrValue.startsWith('0x') ? attrValue : '0x' + Buffer.from(attrValue, 'utf-8').toString('hex'); | ||
return Promise.resolve(_this6.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.setAttribute(_this6.address, attrName, attrValue, exp, overrides)).then(function (setAttrTx) { | ||
return Promise.resolve(setAttrTx.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
revokeAttribute(attrName, attrValue, options = {}) { | ||
try { | ||
const _this7 = this; | ||
// console.log(`revoking attribute ${attrName}(${attrValue}) for ${identity}`) | ||
const overrides = { | ||
gasLimit: 123456, | ||
gasPrice: 1000000000, | ||
...options | ||
}; | ||
attrName = attrName.startsWith('0x') ? attrName : stringToBytes32(attrName); | ||
attrValue = attrValue.startsWith('0x') ? attrValue : '0x' + Buffer.from(attrValue, 'utf-8').toString('hex'); | ||
return Promise.resolve(_this7.attachContract(overrides.from)).then(function (contract) { | ||
delete overrides.from; | ||
return Promise.resolve(contract.functions.revokeAttribute(_this7.address, attrName, attrValue, overrides)).then(function (revokeAttributeTX) { | ||
return Promise.resolve(revokeAttributeTX.wait()); | ||
}); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
} | ||
function populateEventMetaClass(logResult, blockNumber) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const result = {}; | ||
if (logResult.eventFragment.inputs.length !== logResult.args.length) { | ||
throw new TypeError('malformed event input. wrong number of arguments'); | ||
} | ||
logResult.eventFragment.inputs.forEach((input, index) => { | ||
let val = logResult.args[index]; | ||
if (typeof val === 'object') { | ||
val = bignumber.BigNumber.from(val); | ||
} | ||
if (input.type === 'bytes32') { | ||
val = bytes32toString(val); | ||
} | ||
result[input.name] = val; | ||
}); | ||
result._eventName = logResult.name; | ||
result.blockNumber = blockNumber; | ||
return result; | ||
} | ||
function logDecoder(contract, logs) { | ||
const results = logs.map(log => { | ||
const res = contract.interface.parseLog(log); | ||
const event = populateEventMetaClass(res, log.blockNumber); | ||
return event; | ||
}); | ||
return results; | ||
} | ||
function _settle(pact, state, value) { | ||
if (!pact.s) { | ||
if (value instanceof _Pact) { | ||
if (value.s) { | ||
if (state & 1) { | ||
state = value.s; | ||
} | ||
value = value.v; | ||
} else { | ||
value.o = _settle.bind(null, pact, state); | ||
return; | ||
} | ||
} | ||
if (value && value.then) { | ||
value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2)); | ||
return; | ||
} | ||
pact.s = state; | ||
pact.v = value; | ||
const observer = pact.o; | ||
if (observer) { | ||
observer(pact); | ||
} | ||
} | ||
} | ||
const _Pact = /*#__PURE__*/function () { | ||
function _Pact() {} | ||
_Pact.prototype.then = function (onFulfilled, onRejected) { | ||
const result = new _Pact(); | ||
const state = this.s; | ||
if (state) { | ||
const callback = state & 1 ? onFulfilled : onRejected; | ||
if (callback) { | ||
try { | ||
_settle(result, 1, callback(this.v)); | ||
} catch (e) { | ||
_settle(result, 2, e); | ||
} | ||
return result; | ||
} else { | ||
return this; | ||
} | ||
} | ||
this.o = function (_this) { | ||
try { | ||
const value = _this.v; | ||
if (_this.s & 1) { | ||
_settle(result, 1, onFulfilled ? onFulfilled(value) : value); | ||
} else if (onRejected) { | ||
_settle(result, 1, onRejected(value)); | ||
} else { | ||
_settle(result, 2, value); | ||
} | ||
} catch (e) { | ||
_settle(result, 2, e); | ||
} | ||
}; | ||
return result; | ||
}; | ||
return _Pact; | ||
}(); | ||
function _isSettledPact(thenable) { | ||
return thenable instanceof _Pact && thenable.s & 1; | ||
} | ||
function _for(test, update, body) { | ||
var stage; | ||
for (;;) { | ||
var shouldContinue = test(); | ||
if (_isSettledPact(shouldContinue)) { | ||
shouldContinue = shouldContinue.v; | ||
} | ||
if (!shouldContinue) { | ||
return result; | ||
} | ||
if (shouldContinue.then) { | ||
stage = 0; | ||
break; | ||
} | ||
var result = body(); | ||
if (result && result.then) { | ||
if (_isSettledPact(result)) { | ||
result = result.s; | ||
} else { | ||
stage = 1; | ||
break; | ||
} | ||
} | ||
if (update) { | ||
var updateValue = update(); | ||
if (updateValue && updateValue.then && !_isSettledPact(updateValue)) { | ||
stage = 2; | ||
break; | ||
} | ||
} | ||
} | ||
var pact = new _Pact(); | ||
var reject = _settle.bind(null, pact, 2); | ||
(stage === 0 ? shouldContinue.then(_resumeAfterTest) : stage === 1 ? result.then(_resumeAfterBody) : updateValue.then(_resumeAfterUpdate)).then(void 0, reject); | ||
return pact; | ||
function _resumeAfterBody(value) { | ||
result = value; | ||
do { | ||
if (update) { | ||
updateValue = update(); | ||
if (updateValue && updateValue.then && !_isSettledPact(updateValue)) { | ||
updateValue.then(_resumeAfterUpdate).then(void 0, reject); | ||
return; | ||
} | ||
} | ||
shouldContinue = test(); | ||
if (!shouldContinue || _isSettledPact(shouldContinue) && !shouldContinue.v) { | ||
_settle(pact, 1, result); | ||
return; | ||
} | ||
if (shouldContinue.then) { | ||
shouldContinue.then(_resumeAfterTest).then(void 0, reject); | ||
return; | ||
} | ||
result = body(); | ||
if (_isSettledPact(result)) { | ||
result = result.v; | ||
} | ||
} while (!result || !result.then); | ||
result.then(_resumeAfterBody).then(void 0, reject); | ||
} | ||
function _resumeAfterTest(shouldContinue) { | ||
if (shouldContinue) { | ||
result = body(); | ||
if (result && result.then) { | ||
result.then(_resumeAfterBody).then(void 0, reject); | ||
} else { | ||
_resumeAfterBody(result); | ||
} | ||
} else { | ||
_settle(pact, 1, result); | ||
} | ||
} | ||
function _resumeAfterUpdate() { | ||
if (shouldContinue = test()) { | ||
if (shouldContinue.then) { | ||
shouldContinue.then(_resumeAfterTest).then(void 0, reject); | ||
} else { | ||
_resumeAfterTest(shouldContinue); | ||
} | ||
} else { | ||
_settle(pact, 1, result); | ||
} | ||
} | ||
} | ||
function _catch(body, recover) { | ||
try { | ||
var result = body(); | ||
} catch (e) { | ||
return recover(e); | ||
} | ||
if (result && result.then) { | ||
return result.then(void 0, recover); | ||
} | ||
return result; | ||
} | ||
function getResolver(options) { | ||
return new EthrDidResolver(options).build(); | ||
} | ||
class EthrDidResolver { | ||
constructor(options) { | ||
this.contracts = void 0; | ||
this.contracts = configureResolverWithNetworks(options); | ||
} | ||
/** | ||
* returns the current owner of a DID (represented by an address or public key) | ||
* | ||
* @param address | ||
*/ | ||
getOwner(address, networkId, blockTag) { | ||
try { | ||
const _this = this; | ||
//TODO: check if address or public key | ||
return Promise.resolve(new EthrDidController(address, _this.contracts[networkId]).getOwner(address, blockTag)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
/** | ||
* returns the previous change | ||
* | ||
* @param address | ||
*/ | ||
previousChange(address, networkId, blockTag) { | ||
try { | ||
const _this2 = this; | ||
return Promise.resolve(_this2.contracts[networkId].functions.changed(address, { | ||
blockTag | ||
})).then(function (result) { | ||
// console.log(`last change result: '${BigNumber.from(result['0'])}'`) | ||
return bignumber.BigNumber.from(result['0']); | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
getBlockMetadata(blockHeight, networkId) { | ||
try { | ||
const _this3 = this; | ||
return Promise.resolve(_this3.contracts[networkId].provider.getBlock(blockHeight)).then(function (block) { | ||
return { | ||
height: block.number.toString(), | ||
isoDate: new Date(block.timestamp * 1000).toISOString().replace('.000', '') | ||
}; | ||
}); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
changeLog(identity, networkId, blockTag = 'latest') { | ||
try { | ||
const _this4 = this; | ||
function _temp3(_provider$getNetwork) { | ||
const chainId = hexChainId ? _provider$getNetwork : _provider$getNetwork.chainId; | ||
const history = []; | ||
const { | ||
address, | ||
publicKey | ||
} = interpretIdentifier(identity); | ||
const controllerKey = publicKey; | ||
return Promise.resolve(_this4.previousChange(address, networkId, blockTag)).then(function (previousChange) { | ||
function _temp2() { | ||
return { | ||
address, | ||
history, | ||
controllerKey, | ||
chainId | ||
}; | ||
} | ||
const _temp = _for(function () { | ||
return !!previousChange; | ||
}, void 0, function () { | ||
const blockNumber = previousChange; // console.log(`gigel ${previousChange}`) | ||
return Promise.resolve(provider.getLogs({ | ||
address: contract.address, | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
topics: [null, `0x000000000000000000000000${address.slice(2)}`], | ||
fromBlock: previousChange.toHexString(), | ||
toBlock: previousChange.toHexString() | ||
})).then(function (logs) { | ||
const events = logDecoder(contract, logs); | ||
events.reverse(); | ||
previousChange = null; | ||
for (const event of events) { | ||
history.unshift(event); | ||
if (event.previousChange.lt(blockNumber)) { | ||
previousChange = event.previousChange; | ||
} | ||
} | ||
}); | ||
}); | ||
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp); | ||
}); | ||
} | ||
const contract = _this4.contracts[networkId]; | ||
const provider = contract.provider; | ||
const hexChainId = networkId.startsWith('0x') ? networkId : knownNetworks[networkId]; //TODO: this can be used to check if the configuration is ok | ||
return Promise.resolve(hexChainId ? _temp3(bignumber.BigNumber.from(hexChainId).toNumber()) : Promise.resolve(provider.getNetwork()).then(_temp3)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
wrapDidDocument(did, address, controllerKey, history, chainId, blockHeight, now) { | ||
var _didDocument$verifica; | ||
const baseDIDDocument = { | ||
'@context': ['https://www.w3.org/ns/did/v1', 'https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld'], | ||
id: did, | ||
verificationMethod: [], | ||
authentication: [], | ||
assertionMethod: [] | ||
}; | ||
let controller = address; | ||
const authentication = [`${did}#controller`]; | ||
let versionId = 0; | ||
let nextVersionId = Number.POSITIVE_INFINITY; | ||
let deactivated = false; | ||
let delegateCount = 0; | ||
let serviceCount = 0; | ||
const auth = {}; | ||
const pks = {}; | ||
const services = {}; | ||
for (const event of history) { | ||
if (blockHeight !== -1 && event.blockNumber > blockHeight) { | ||
if (nextVersionId > event.blockNumber) { | ||
nextVersionId = event.blockNumber; | ||
} | ||
continue; | ||
} else { | ||
if (versionId < event.blockNumber) { | ||
versionId = event.blockNumber; | ||
} | ||
} | ||
const validTo = event.validTo || bignumber.BigNumber.from(0); | ||
const eventIndex = `${event._eventName}-${event.delegateType || event.name}-${event.delegate || event.value}`; | ||
if (validTo && validTo.gte(now)) { | ||
if (event._eventName === eventNames.DIDDelegateChanged) { | ||
const currentEvent = event; | ||
delegateCount++; | ||
const delegateType = currentEvent.delegateType; //conversion from bytes32 is done in logParser | ||
switch (delegateType) { | ||
case 'sigAuth': | ||
auth[eventIndex] = `${did}#delegate-${delegateCount}`; | ||
// eslint-disable-line no-fallthrough | ||
case 'veriKey': | ||
pks[eventIndex] = { | ||
id: `${did}#delegate-${delegateCount}`, | ||
type: exports.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020, | ||
controller: did, | ||
blockchainAccountId: `${currentEvent.delegate}@eip155:${chainId}` | ||
}; | ||
break; | ||
} | ||
} else if (event._eventName === eventNames.DIDAttributeChanged) { | ||
const currentEvent = event; | ||
const name = currentEvent.name; //conversion from bytes32 is done in logParser | ||
const match = name.match(/^did\/(pub|svc)\/(\w+)(\/(\w+))?(\/(\w+))?$/); | ||
if (match) { | ||
const section = match[1]; | ||
const algorithm = match[2]; | ||
const type = legacyAttrTypes[match[4]] || match[4]; | ||
const encoding = match[6]; | ||
switch (section) { | ||
case 'pub': | ||
{ | ||
delegateCount++; | ||
const pk = { | ||
id: `${did}#delegate-${delegateCount}`, | ||
type: `${algorithm}${type}`, | ||
controller: did | ||
}; | ||
pk.type = legacyAlgoMap[pk.type] || algorithm; | ||
switch (encoding) { | ||
case null: | ||
case undefined: | ||
case 'hex': | ||
pk.publicKeyHex = currentEvent.value.slice(2); | ||
break; | ||
case 'base64': | ||
pk.publicKeyBase64 = Buffer.from(currentEvent.value.slice(2), 'hex').toString('base64'); | ||
break; | ||
case 'base58': | ||
pk.publicKeyBase58 = basex.Base58.encode(Buffer.from(currentEvent.value.slice(2), 'hex')); | ||
break; | ||
case 'pem': | ||
pk.publicKeyPem = Buffer.from(currentEvent.value.slice(2), 'hex').toString(); | ||
break; | ||
default: | ||
pk.value = currentEvent.value; | ||
} | ||
pks[eventIndex] = pk; | ||
if (match[4] === 'sigAuth') { | ||
auth[eventIndex] = pk.id; | ||
} | ||
break; | ||
} | ||
case 'svc': | ||
serviceCount++; | ||
services[eventIndex] = { | ||
id: `${did}#service-${serviceCount}`, | ||
type: algorithm, | ||
serviceEndpoint: Buffer.from(currentEvent.value.slice(2), 'hex').toString() | ||
}; | ||
break; | ||
} | ||
} | ||
} | ||
} else if (event._eventName === eventNames.DIDOwnerChanged) { | ||
const currentEvent = event; | ||
controller = currentEvent.owner; | ||
if (currentEvent.owner === nullAddress) { | ||
deactivated = true; | ||
break; | ||
} | ||
} else { | ||
if (event._eventName === eventNames.DIDDelegateChanged || event._eventName === eventNames.DIDAttributeChanged && event.name.match(/^did\/pub\//)) { | ||
delegateCount++; | ||
} else if (event._eventName === eventNames.DIDAttributeChanged && event.name.match(/^did\/svc\//)) { | ||
serviceCount++; | ||
} | ||
delete auth[eventIndex]; | ||
delete pks[eventIndex]; | ||
delete services[eventIndex]; | ||
} | ||
} | ||
const publicKeys = [{ | ||
id: `${did}#controller`, | ||
type: exports.verificationMethodTypes.EcdsaSecp256k1RecoveryMethod2020, | ||
controller: did, | ||
blockchainAccountId: `${controller}@eip155:${chainId}` | ||
}]; | ||
if (controllerKey && controller == address) { | ||
publicKeys.push({ | ||
id: `${did}#controllerKey`, | ||
type: exports.verificationMethodTypes.EcdsaSecp256k1VerificationKey2019, | ||
controller: did, | ||
publicKeyHex: controllerKey | ||
}); | ||
authentication.push(`${did}#controllerKey`); | ||
} | ||
const didDocument = { ...baseDIDDocument, | ||
verificationMethod: publicKeys.concat(Object.values(pks)), | ||
authentication: authentication.concat(Object.values(auth)) | ||
}; | ||
if (Object.values(services).length > 0) { | ||
didDocument.service = Object.values(services); | ||
} | ||
didDocument.assertionMethod = [...(((_didDocument$verifica = didDocument.verificationMethod) == null ? void 0 : _didDocument$verifica.map(pk => pk.id)) || [])]; | ||
return deactivated ? { | ||
didDocument: { ...baseDIDDocument, | ||
'@context': 'https://www.w3.org/ns/did/v1' | ||
}, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
} : { | ||
didDocument, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
}; | ||
} | ||
resolve(did, parsed, // eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
_unused, options) { | ||
try { | ||
const _this5 = this; | ||
function _temp9() { | ||
return Promise.resolve(_this5.changeLog(id, networkId, 'latest')).then(function ({ | ||
address, | ||
history, | ||
controllerKey, | ||
chainId | ||
}) { | ||
return _catch(function () { | ||
function _temp7() { | ||
function _temp5() { | ||
return { | ||
didDocumentMetadata: { ...status, | ||
...versionMeta, | ||
...versionMetaNext | ||
}, | ||
didResolutionMetadata: { | ||
contentType: 'application/did+ld+json' | ||
}, | ||
didDocument | ||
}; | ||
} | ||
const _temp4 = function () { | ||
if (nextVersionId !== Number.POSITIVE_INFINITY) { | ||
return Promise.resolve(_this5.getBlockMetadata(nextVersionId, networkId)).then(function (block) { | ||
versionMetaNext = { | ||
nextVersionId: block.height, | ||
nextUpdate: block.isoDate | ||
}; | ||
}); | ||
} | ||
}(); | ||
return _temp4 && _temp4.then ? _temp4.then(_temp5) : _temp5(_temp4); | ||
} | ||
const { | ||
didDocument, | ||
deactivated, | ||
versionId, | ||
nextVersionId | ||
} = _this5.wrapDidDocument(did, address, controllerKey, history, chainId, blockTag, now); | ||
const status = deactivated ? { | ||
deactivated: true | ||
} : {}; | ||
let versionMeta = {}; | ||
let versionMetaNext = {}; | ||
const _temp6 = function () { | ||
if (versionId !== 0) { | ||
return Promise.resolve(_this5.getBlockMetadata(versionId, networkId)).then(function (block) { | ||
versionMeta = { | ||
versionId: block.height, | ||
updated: block.isoDate | ||
}; | ||
}); | ||
} | ||
}(); | ||
return _temp6 && _temp6.then ? _temp6.then(_temp7) : _temp7(_temp6); | ||
}, function (e) { | ||
return { | ||
didResolutionMetadata: { | ||
error: exports.Errors.notFound, | ||
message: e.toString() // This is not in spec, nut may be helpful | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}; | ||
}); | ||
}); | ||
} | ||
const fullId = parsed.id.match(identifierMatcher); | ||
if (!fullId) { | ||
return Promise.resolve({ | ||
didResolutionMetadata: { | ||
error: exports.Errors.invalidDid, | ||
message: `Not a valid did:ethr: ${parsed.id}` | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}); | ||
} | ||
const id = fullId[2]; | ||
const networkId = !fullId[1] ? 'mainnet' : fullId[1].slice(0, -1); | ||
let blockTag = options.blockTag || 'latest'; | ||
if (typeof parsed.query === 'string') { | ||
const qParams = qs__namespace.decode(parsed.query); | ||
blockTag = typeof qParams['versionId'] === 'string' ? qParams['versionId'] : blockTag; | ||
try { | ||
blockTag = Number.parseInt(blockTag); | ||
} catch (e) { | ||
blockTag = 'latest'; // invalid versionId parameters are ignored | ||
} | ||
} | ||
if (!_this5.contracts[networkId]) { | ||
return Promise.resolve({ | ||
didResolutionMetadata: { | ||
error: exports.Errors.unknownNetwork, | ||
message: `The DID resolver does not have a configuration for network: ${networkId}` | ||
}, | ||
didDocumentMetadata: {}, | ||
didDocument: null | ||
}); | ||
} | ||
let now = bignumber.BigNumber.from(Math.floor(new Date().getTime() / 1000)); | ||
const _temp8 = function () { | ||
if (typeof blockTag === 'number') { | ||
return Promise.resolve(_this5.getBlockMetadata(blockTag, networkId)).then(function (block) { | ||
now = bignumber.BigNumber.from(Date.parse(block.isoDate) / 1000); | ||
}); | ||
} | ||
}(); | ||
return Promise.resolve(_temp8 && _temp8.then ? _temp8.then(_temp9) : _temp9(_temp8)); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
build() { | ||
return { | ||
ethr: this.resolve.bind(this) | ||
}; | ||
} | ||
} | ||
exports.EthrDidController = EthrDidController; | ||
exports.REGISTRY = DEFAULT_REGISTRY_ADDRESS; | ||
exports.attrTypes = legacyAttrTypes; | ||
exports.bytes32toString = bytes32toString; | ||
exports.delegateTypes = legacyAlgoMap; | ||
exports.getResolver = getResolver; | ||
exports.identifierMatcher = identifierMatcher; | ||
exports.interpretIdentifier = interpretIdentifier; | ||
exports.stringToBytes32 = stringToBytes32; | ||
}))); | ||
//# sourceMappingURL=index.umd.js.map |
@@ -5,1 +5,2 @@ import { Contract } from '@ethersproject/contracts'; | ||
export declare function logDecoder(contract: Contract, logs: Log[]): ERC1056Event[]; | ||
//# sourceMappingURL=logParser.d.ts.map |
@@ -41,1 +41,2 @@ import { BigNumber } from '@ethersproject/bignumber'; | ||
} | ||
//# sourceMappingURL=resolver.d.ts.map |
{ | ||
"name": "ethr-did-resolver", | ||
"version": "4.3.3", | ||
"description": "Resolve DID documents around ethereum addresses", | ||
"main": "lib/index.umd.js", | ||
"version": "4.3.4", | ||
"description": "Resolve DID documents for ethereum addresses and public keys", | ||
"source": "src/index.ts", | ||
"module": "lib/index.modern.js", | ||
"main": "lib/index.js", | ||
"module": "lib/index.module.js", | ||
"unpkg": "lib/index.umd.js", | ||
"types": "lib/index.d.ts", | ||
"umd:main": "lib/index.umd.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/decentralized-identity/ethr-did-resolver.git" | ||
"url": "git@github.com:decentralized-identity/ethr-did-resolver.git" | ||
}, | ||
"files": [ | ||
"index.d.ts", | ||
"dist", | ||
"lib", | ||
"contracts", | ||
"src", | ||
"LICENSE", | ||
"babel-preset.js", | ||
".babelrc" | ||
"LICENSE" | ||
], | ||
"author": "Pelle Braendgaard <pelle.braendgaard@consensys.net>", | ||
"author": "Pelle Braendgaard", | ||
"contributors": [ | ||
@@ -29,2 +26,3 @@ "Mircea Nistor <mircea.nistor@mesh.xyz>" | ||
"keywords": [ | ||
"did:ethr", | ||
"DID", | ||
@@ -34,3 +32,2 @@ "DID document", | ||
"resolver", | ||
"resolve", | ||
"Verifiable Credential", | ||
@@ -44,35 +41,50 @@ "W3C", | ||
"EcdsaSecp256k1RecoveryMethod2020", | ||
"Ed25519VerificationKey2018", | ||
"did:ethr" | ||
"EcdsaSecp256k1VerificationKey2019", | ||
"Ed25519VerificationKey2018" | ||
], | ||
"scripts": { | ||
"build": "microbundle", | ||
"lint": "eslint \"src/**/*.[jt]s\"", | ||
"test": "jest", | ||
"test:ci": "jest --coverage && codecov", | ||
"build:js": "microbundle --compress=false", | ||
"build": "yarn lint && yarn build:js && yarn test", | ||
"format": "prettier --write \"src/**/*.[jt]s\"", | ||
"prepare": "npm run build", | ||
"prepublishOnly": "npm test && npm run build", | ||
"release": "semantic-release --debug", | ||
"test": "jest", | ||
"test-with-coverage": "jest --coverage && codecov" | ||
"lint": "eslint --ignore-pattern \"src/**/*.test.[jt]s\" \"src/**/*.[jt]s\"", | ||
"prepare": "yarn build", | ||
"prepublishOnly": "yarn test:ci && yarn format && yarn lint", | ||
"release": "semantic-release --debug" | ||
}, | ||
"jest": { | ||
"clearMocks": true, | ||
"collectCoverageFrom": [ | ||
"src/**/*.{ts,tsx}", | ||
"!src/**/*.d.ts", | ||
"!**/node_modules/**", | ||
"!**/__tests__/**" | ||
], | ||
"testEnvironment": "node", | ||
"testMatch": [ | ||
"**/__tests__/**/*.test.[jt]s" | ||
] | ||
}, | ||
"devDependencies": { | ||
"@babel/core": "7.13.16", | ||
"@babel/preset-env": "7.13.15", | ||
"@babel/preset-typescript": "7.13.0", | ||
"@babel/core": "7.14.6", | ||
"@babel/preset-env": "7.14.7", | ||
"@babel/preset-typescript": "7.14.5", | ||
"@semantic-release/changelog": "5.0.1", | ||
"@semantic-release/git": "9.0.0", | ||
"@types/jest": "26.0.22", | ||
"@typescript-eslint/eslint-plugin": "4.22.0", | ||
"@typescript-eslint/parser": "4.22.0", | ||
"babel-jest": "26.6.3", | ||
"codecov": "3.8.1", | ||
"eslint": "7.24.0", | ||
"eslint-config-prettier": "8.2.0", | ||
"@types/jest": "26.0.23", | ||
"@typescript-eslint/eslint-plugin": "4.28.0", | ||
"@typescript-eslint/parser": "4.28.0", | ||
"babel-jest": "27.0.5", | ||
"codecov": "3.8.2", | ||
"eslint": "7.29.0", | ||
"eslint-config-prettier": "8.3.0", | ||
"eslint-plugin-jest": "24.3.6", | ||
"eslint-plugin-prettier": "3.4.0", | ||
"ganache-cli": "6.12.2", | ||
"jest": "26.6.3", | ||
"microbundle": "0.13.0", | ||
"prettier": "2.2.1", | ||
"pretty-quick": "3.1.0", | ||
"semantic-release": "17.4.2", | ||
"typescript": "4.2.4" | ||
"jest": "27.0.5", | ||
"microbundle": "0.13.3", | ||
"prettier": "2.3.1", | ||
"semantic-release": "17.4.4", | ||
"typescript": "4.3.4" | ||
}, | ||
@@ -79,0 +91,0 @@ "dependencies": { |
@@ -1,19 +0,12 @@ | ||
--- | ||
title: "Ethr DID Resolver" | ||
index: 7 category: "ethr-did-resolver" | ||
type: "reference" | ||
source: "https://github.com/decentralized-identity/ethr-did-resolver/blob/develop/README.md" | ||
--- | ||
[![npm](https://img.shields.io/npm/dt/ethr-did-resolver.svg)](https://www.npmjs.com/package/ethr-did-resolver) | ||
[![npm](https://img.shields.io/npm/v/ethr-did-resolver.svg)](https://www.npmjs.com/package/ethr-did-resolver) | ||
[![codecov](https://codecov.io/gh/decentralized-identity/ethr-did-resolver/branch/develop/graph/badge.svg)](https://codecov.io/gh/decentralized-identity/ethr-did-resolver) | ||
# ethr DID Resolver | ||
[![codecov](https://codecov.io/gh/decentralized-identity/ethr-did-resolver/branch/develop/graph/badge.svg)](https://codecov.io/gh/decentralized-identity/ethr-did-resolver) | ||
[![CircleCI](https://circleci.com/gh/decentralized-identity/ethr-did-resolver.svg?style=svg)](https://circleci.com/gh/decentralized-identity/ethr-did-resolver) | ||
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/7bcde296af8e467787b04c956c2c9f6f)](https://www.codacy.com/manual/uport-project/ethr-did-resolver?utm_source=github.com&utm_medium=referral&utm_content=uport-project/ethr-did-resolver&utm_campaign=Badge_Grade) | ||
This library is intended to use ethereum addresses or secp256k1 publicKeys as fully self-managed | ||
[Decentralized Identifiers](https://w3c-ccg.github.io/did-spec/#decentralized-identifiers-dids) and wrap them in a | ||
[DID Document](https://w3c-ccg.github.io/did-spec/#did-documents) | ||
[Decentralized Identifiers](https://w3c.github.io/did-core/#identifier) and wrap them in a | ||
[DID Document](https://w3c.github.io/did-core/#did-document-properties) | ||
It supports the proposed [Decentralized Identifiers](https://w3c-ccg.github.io/did-spec/) spec from the | ||
It supports the proposed [Decentralized Identifiers](https://w3c.github.io/did-core/#identifier) spec from the | ||
[W3C Credentials Community Group](https://w3c-ccg.github.io). | ||
@@ -41,5 +34,5 @@ | ||
The did resolver takes the ethereum address, looks at contract events and builds a DID document based on the ERC1056 Events | ||
corresponding to the address. When an identifier is a full `publicKey`, the corresponding `ethereumAddress` is computed | ||
and checked in the same manner. | ||
The did resolver takes the ethereum address, looks at contract events and builds a DID document based on the ERC1056 | ||
Events corresponding to the address. When an identifier is a full `publicKey`, the corresponding `ethereumAddress` is | ||
computed and checked in the same manner. | ||
@@ -64,11 +57,16 @@ The minimal DID document for an ethereum address `0xb9c5714089478a327f09197987f16f9e5d936e8a` with no transactions to | ||
], | ||
"authentication": ["did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a#controller"], | ||
"assertionMethod": ["did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a#controller"] | ||
"authentication": [ | ||
"did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a#controller" | ||
], | ||
"assertionMethod": [ | ||
"did:ethr:0xb9c5714089478a327f09197987f16f9e5d936e8a#controller" | ||
] | ||
} | ||
``` | ||
Note this resolver uses the `EcdsaSecp256k1RecoveryMethod2020` type and an `blockchainAccountId` to represent the default | ||
`verificationMethod`, `assertionMethod`, and `authentication` entry. | ||
Any value from the registry that returns an ethereum address will be added to the `verificationMethod` array of the DID | ||
document with type `EcdsaSecp256k1RecoveryMethod2020` and an `blockchainAccountId` attribute containing the address. | ||
Note this resolver uses the `EcdsaSecp256k1RecoveryMethod2020` type and an `blockchainAccountId` to represent the | ||
default | ||
`verificationMethod`, `assertionMethod`, and `authentication` entry. Any value from the registry that returns an | ||
ethereum address will be added to the `verificationMethod` array of the DID document with | ||
type `EcdsaSecp256k1RecoveryMethod2020` and an `blockchainAccountId` attribute containing the address. | ||
@@ -85,4 +83,4 @@ ## Building a DID document | ||
The library presents a `resolve()` function that returns a `Promise` returning the DID document. It is not meant to | ||
be used directly but through the [`did-resolver`](https://github.com/decentralized-identity/did-resolver) aggregator. | ||
The library presents a `resolve()` function that returns a `Promise` returning the DID document. It is not meant to be | ||
used directly but through the [`did-resolver`](https://github.com/decentralized-identity/did-resolver) aggregator. | ||
@@ -89,0 +87,0 @@ You can use the `getResolver(config)` method to produce an entry that can be used with the `Resolver` |
@@ -84,4 +84,3 @@ import { Base58 } from '@ethersproject/basex' | ||
//TODO: this can be used to check if the configuration is ok | ||
const chainIdFromNetwork = (await provider.getNetwork()).chainId | ||
const chainId = hexChainId ? BigNumber.from(hexChainId).toNumber() : chainIdFromNetwork | ||
const chainId = hexChainId ? BigNumber.from(hexChainId).toNumber() : (await provider.getNetwork()).chainId | ||
const history: ERC1056Event[] = [] | ||
@@ -88,0 +87,0 @@ const { address, publicKey } = interpretIdentifier(identity) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
510927
37
6391
1
20
144