Skip to content

Commit

Permalink
Merge pull request #18 from ayanworks/POLYNDI-44-update-polygon-did-r…
Browse files Browse the repository at this point in the history
…egistrar

feat: implemented linked-resource methods
  • Loading branch information
sairanjit authored Jan 9, 2024
2 parents e73c88b + 71ae7de commit 584ecc7
Show file tree
Hide file tree
Showing 6 changed files with 427 additions and 98 deletions.
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"clean": "rm -rf build",
"clean:deps": "pnpm clean && rm -rf node_modules",
"build": "pnpm clean && tsc",
"test": "node --require ts-node/register --test ./tests/*.test.ts",
"test": "node --require ts-node/register --test ./tests/polygon.test.ts",
"prettier": "prettier --ignore-path .prettierignore .",
"check-format": "pnpm prettier --list-different",
"check-types": "pnpm build --noEmit",
Expand All @@ -19,15 +19,17 @@
],
"license": "MIT",
"dependencies": {
"@ayanworks/polygon-did-registry-contract": "2.0.1-alpha.2",
"@ayanworks/polygon-did-registry-contract": "2.0.1-alpha.3",
"@ethersproject/basex": "^5.7.0",
"@ethersproject/signing-key": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
"@ethersproject/wallet": "^5.7.0",
"ethers": "^6.9.0"
"ethers": "^6.9.0",
"uuid": "^9.0.1"
},
"devDependencies": {
"@types/node": "^18.17.0",
"@types/uuid": "^9.0.7",
"prettier": "^3.0.2",
"release-it": "^16.1.5",
"ts-node": "^10.9.1",
Expand Down
23 changes: 19 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

174 changes: 151 additions & 23 deletions src/registrar.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Contract, JsonRpcProvider, Wallet, computeAddress } from 'ethers'
import { wrapDidDocument } from './polygon-did-registrar'
import { parseDid, validateDid } from './utils/did'
import { validateResourcePayload } from './utils/linkedResource'
import DidRegistryContract from '@ayanworks/polygon-did-registry-contract'
import { Base58 } from '@ethersproject/basex'
import { computePublicKey } from '@ethersproject/signing-key'
import { v4 as uuidv4 } from 'uuid'

export type PolygonDidInitOptions = {
contractAddress: string
Expand All @@ -17,6 +19,19 @@ export type PolygonDidRegisterOptions = {
serviceEndpoint?: string
}

export type ResourcePayload = {
resourceURI: string
resourceCollectionId: string
resourceId: string
resourceName: string
resourceType: string
mediaType: string
created: string
checksum: string
previousVersionId: string | null
nextVersionId: string | null
}

export class PolygonDID {
private registry: Contract

Expand All @@ -35,6 +50,7 @@ export class PolygonDID {
}

static createKeyPair(network: string) {
let did: string = ''
const wallet = Wallet.createRandom()
const privateKey = wallet.privateKey
const address = computeAddress(privateKey)
Expand All @@ -44,12 +60,14 @@ export class PolygonDID {
const bufferPublicKey = Buffer.from(publicKey)
const publicKeyBase58 = Base58.encode(bufferPublicKey)

if (network !== ('testnet' || 'mainnet')) {
if (network !== 'testnet' && network !== 'mainnet') {
throw new Error('Invalid network provided')
}

const did = `did:polygon:${network}:${address}`

if (network === 'mainnet') {
did = `did:polygon:${address}`
} else {
did = `did:polygon:${network}:${address}`
}
return { address, privateKey, publicKeyBase58, did }
}

Expand All @@ -68,7 +86,7 @@ export class PolygonDID {

const resolveDidDoc = await this.registry.getDIDDoc(parsedDid.didAddress)

if (resolveDidDoc) {
if (resolveDidDoc[0]) {
throw new Error('The DID document already registered!')
}

Expand All @@ -92,51 +110,151 @@ export class PolygonDID {
didDoc,
}
} catch (error) {
console.log(`Error occurred in registerDID function ${error}`)
console.log(`Error occurred in registerDID function ${error} `)
throw error
}
}

public async update(did: string, didDoc: string) {
public async update(did: string, didDoc: object) {
try {
const isValidDid = validateDid(did)
if (!isValidDid) {
throw new Error('invalid did provided')
throw new Error('Invalid did provided')
}

const parsedDid = parseDid(did)

if (!didDoc && !JSON.parse(didDoc)) {
throw new Error('Invalid DID has been entered!')
}
const didDocJson = JSON.parse(didDoc)

if (
!didDocJson['@context'] ||
!didDocJson['id'] ||
!didDocJson['verificationMethod']
) {
throw new Error('Invalid DID doc')
}

// Calling smart contract with update DID document on matic chain
const txnHash = await this.registry.updateDIDDoc(
parsedDid.didAddress,
JSON.stringify(didDoc),
)
return {
did,
didDoc,
txnHash,
}
} catch (error) {
console.log(`Error occurred in update ${error} `)
throw error
}
}

public async addResource(did: string, resourcePayload: ResourcePayload) {
try {
const isValidDid = validateDid(did)
if (!isValidDid) {
throw new Error('Invalid did provided')
}

const parsedDid = parseDid(did)

validateResourcePayload(resourcePayload)

const resolveDidDoc = await this.registry.getDIDDoc(parsedDid.didAddress)

if (!resolveDidDoc[0]) {
throw new Error(`The DID document for the given DID was not found!`)
}

const stringDidDoc = JSON.stringify(resourcePayload)
const resourceId = uuidv4()

const txnHash = await this.registry.addResource(
parsedDid.didAddress,
resourceId,
stringDidDoc,
)

return {
did,
didDoc,
resourceId,
txnHash,
}
} catch (error) {
console.log(`Error occurred in addResource function ${error} `)
throw error
}
}

public async updateResource(
did: string,
resourceId: string,
resourcePayload: ResourcePayload,
) {
try {
const isValidDid = validateDid(did)
if (!isValidDid && resourceId) {
throw new Error('Invalid DID or resourceId provided!')
}

const parsedDid = parseDid(did)

validateResourcePayload(resourcePayload)

const resolveDidDoc = await this.registry.getDIDDoc(parsedDid.didAddress)

if (!resolveDidDoc[0]) {
throw new Error(`The DID document for the given DID was not found!`)
}

const stringDidDoc = JSON.stringify(resourcePayload)

const txnHash = await this.registry.addResource(
parsedDid.didAddress,
resourceId,
stringDidDoc,
)

return {
did,
resourceId,
txnHash,
}
} catch (error) {
console.log(`Error occurred in update ${error}`)
console.log(`Error occurred in addResource function ${error} `)
throw error
}
}

public async deactivate(did: string) {
public async getResourceByDidAndResourceId(did: string, resourceId: string) {
try {
const isValidDid = validateDid(did)

if (!isValidDid) {
throw new Error('Invalid did provided')
}

const parsedDid = parseDid(did)

const resolveDidDoc = await this.registry.getDIDDoc(parsedDid.didAddress)

if (!resolveDidDoc[0]) {
throw new Error(`The DID document for the given DID was not found!`)
}

const linkedResource = await this.registry.getResource(
parsedDid.didAddress,
resourceId,
)

return {
did,
linkedResource: JSON.parse(linkedResource),
}
} catch (error) {
console.log(
`Error occurred in getResourcesByDidAndResourceId function ${error} `,
)
throw error
}
}

public async getResourcesByDid(did: string) {
try {
const isValidDid = validateDid(did)
if (!isValidDid) {
Expand All @@ -145,14 +263,24 @@ export class PolygonDID {

const parsedDid = parseDid(did)

const txnHash = await this.registry.deleteDIDDoc(parsedDid.didAddress)
const resolveDidDoc = await this.registry.getDIDDoc(parsedDid.didAddress)

if (!resolveDidDoc[0]) {
throw new Error(`The DID document for the given DID was not found!`)
}

const listLinkedResource = await this.registry.getAllResources(
parsedDid.didAddress,
)

return {
did,
txnHash,
linkedResources: listLinkedResource.map((element: string) => {
return JSON.parse(element) as ResourcePayload
}),
}
} catch (error) {
console.log(`Error occurred in deactivate ${error}`)
console.log(`Error occurred in getResourcesByDid function ${error} `)
throw error
}
}
Expand Down
Loading

0 comments on commit 584ecc7

Please sign in to comment.