Skip to content

Commit

Permalink
Did resolver server (#18)
Browse files Browse the repository at this point in the history
* resolve did from server

* add server response error

* add tests

Co-authored-by: alpers <alpers@163.com>
  • Loading branch information
linhan-work and linhan-work committed Nov 14, 2022
1 parent 3a26993 commit 7659ea8
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 181 deletions.
3 changes: 1 addition & 2 deletions packages/did-resolver/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"version": "0.0.1-10",
"main": "index.js",
"dependencies": {
"@polkadot/util": "^10.1.11",
"arweave": "^1.11.6"
"axios": "^1.1.3"
}
}
87 changes: 84 additions & 3 deletions packages/did-resolver/src/ArweaveDidResolver.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,100 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import axios, { AxiosInstance } from 'axios';

import { ArweaveDidResolver } from './ArweaveDidResolver';
import { DidNotFoundError, ServerResponseError } from './errors';

// const DID_URI = 'did:zk:0xab62B6Cc152ca32b51fD80CF5eE6c606DEd850c6';
const DID_URI = 'did:zk:0x8A63688576294474862cE18486CD489144721D77';

jest.mock('axios');

const jestAxios: jest.Mocked<AxiosInstance> = axios as any;

const DOCUMENT = {
'@context': ['https://www.w3.org/ns/did/v1'],
assertionMethod: ['did:zk:0x8A63688576294474862cE18486CD489144721D77#key-0'],
authentication: ['did:zk:0x8A63688576294474862cE18486CD489144721D77#key-0'],
capabilityDelegation: ['did:zk:0x8A63688576294474862cE18486CD489144721D77#key-0'],
capabilityInvocation: ['did:zk:0x8A63688576294474862cE18486CD489144721D77#key-0'],
controller: ['did:zk:0x8A63688576294474862cE18486CD489144721D77'],
createdTime: 1666336001243,
id: 'did:zk:0x8A63688576294474862cE18486CD489144721D77',
keyAgreement: ['did:zk:0x8A63688576294474862cE18486CD489144721D77#key-1'],
proof: [
{
id: 'did:zk:0x8A63688576294474862cE18486CD489144721D77#key-0',
signature:
'zMkj3eCzxioVEhSxFJyQPKbZ93bnnWbDafpWmvRke6NfTUW8z1bAXRAXK48wbhqfXZxb3yPEMrN2m9nkSqk5zF6i7S',
type: 'publish'
}
],
service: [],
verificationMethod: [
{
controller: ['did:zk:0x8A63688576294474862cE18486CD489144721D77'],
id: 'did:zk:0x8A63688576294474862cE18486CD489144721D77#key-0',
publicKeyMultibase: 'z25LmFwNQi68JRGhMxqWYdPUDi1Mrntrd22bzEoiXVqcs5',
type: 'EcdsaSecp256k1VerificationKey2019'
},
{
controller: ['did:zk:0x8A63688576294474862cE18486CD489144721D77'],
id: 'did:zk:0x8A63688576294474862cE18486CD489144721D77#key-1',
publicKeyMultibase: 'z3SF5idgW4q6MHgaCFvUVmRsPa9hWq6iYj8WULqaXuzDe',
type: 'X25519KeyAgreementKey2019'
}
]
};

describe('ArweaveDidResolver', (): void => {
let resolver: ArweaveDidResolver;

beforeEach(() => {
resolver = new ArweaveDidResolver();
});

it.skip('resolve didUrl', async (): Promise<void> => {
console.log(await resolver.resolve(DID_URI));
it('resolve didUrl from server', async (): Promise<void> => {
jestAxios.get.mockResolvedValue({
data: {
code: 200,
data: {
_id: '6371f66c7b64987021e67afd',
status: 3,
rawData: DOCUMENT,
id: 'did:zk:0x8A63688576294474862cE18486CD489144721D77',
__v: 0
},
message: 'operation successful'
}
});

const res = await resolver.resolve(DID_URI);

expect(res).toStrictEqual(DOCUMENT);
});

it('should throw DidNotFoundError', () => {
jestAxios.get.mockResolvedValue({
data: {
code: 200,
data: null,
message: 'operation successful'
}
});

expect(() => resolver.resolve(DID_URI)).rejects.toThrow(DidNotFoundError);
});

it('should throw ServerResponseError', () => {
jestAxios.get.mockResolvedValue({
data: {
code: 500,
data: null,
message: 'unknown error'
}
});

expect(() => resolver.resolve(DID_URI)).rejects.toThrow(ServerResponseError);
});
});
65 changes: 12 additions & 53 deletions packages/did-resolver/src/ArweaveDidResolver.ts
Original file line number Diff line number Diff line change
@@ -1,81 +1,40 @@
// Copyright 2021-2022 zcloak authors & contributors
// SPDX-License-Identifier: Apache-2.0

import { isArray } from '@polkadot/util';
import Arweave from 'arweave';
import axios from 'axios';

import { DidResolver } from './DidResolver';
import { DidNotFoundError, RepresentationNotSupportedError } from './errors';
import { DidNotFoundError, ServerResponseError } from './errors';
import { DidDocument } from './types';

interface Options {
host?: string;
protocol?: string;
owners?: string[];
server?: string;
}

export class ArweaveDidResolver extends DidResolver {
public arweave: Arweave;
public owners: string[];
public server: string;

constructor(opts: Options = {}) {
super();

const {
host = 'arweave.net',
owners = ['rfHpFtImP9jqcXvrl3aZSLPoqa_5mgN5yQO-bWusA7A'],
protocol = 'https'
} = opts;
const { server = 'https://did-service.starks.network' } = opts;

this.owners = owners;
// eslint-disable-next-line no-unsafe-optional-chaining
this.arweave = (Arweave.init ?? (Arweave as any)?.default?.init)({
host,
protocol
});
this.server = server;
}

public override async resolve(didUrl: string): Promise<DidDocument> {
const { did } = this.parseDid(didUrl);

const res = await this.arweave.api.post('/graphql', {
query: `query {
transactions(
owners: ${JSON.stringify(this.owners)},
tags: { name: "didUrl", values: ["${did}"] }
) {
edges {
node {
id
}
const res = await axios.get(`${this.server}/did/${did}`);

if (res.data.code !== 200) {
throw new ServerResponseError(res.data.message);
}
}
}`
});

if (
!res?.data?.data?.transactions?.edges ||
!isArray(res?.data?.data?.transactions?.edges) ||
res?.data?.data?.transactions?.edges.length === 0
) {
if (res.data.code === 200 && !res.data.data) {
throw new DidNotFoundError();
}

try {
const documents: string[] = await Promise.all(
res.data.data.transactions.edges.map(({ node: { id } }: any) =>
this.arweave.transactions.getData(id, {
decode: true,
string: true
})
)
);

const document = JSON.parse(documents[documents.length - 1]);

return document;
} catch {
throw new RepresentationNotSupportedError();
}
return res.data.data.rawData;
}
}
5 changes: 5 additions & 0 deletions packages/did-resolver/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ export class RepresentationNotSupportedError extends Error {
super('representation not supported.');
}
}
export class ServerResponseError extends Error {
constructor(msg: string) {
super(`An exception occurred on the server. ${msg}`);
}
}
Loading

0 comments on commit 7659ea8

Please sign in to comment.