Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TS Client Implementation #15

Merged
merged 1 commit into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ts-client-integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ jobs:

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Set Node.js 16.x
uses: actions/setup-node@v3
with:
node-version: 16.x

- name: Install Dev Dependencies
working-directory: ./ts-client
run: npm install
run: yarn install --frozen-lockfile

- name: Run Anvil Node
run: anvil &

- name: Run tests
working-directory: ./ts-client
run: npm run integration-test
run: yarn run test:integration
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ node_modules/
/broadcast/**/dry-run/

# ts-client files
ts-client/node_modules
ts-client/types
ts-client/dist/
ts-client/node_modules/
ts-client/src/contracts/typechain-types/
ts-client/yarn.lock
# Dotenv file
.env
Expand Down
169 changes: 166 additions & 3 deletions ts-client/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,172 @@
# DID bnb typescript client
# `did:bnb` Client

A typescript client library for registering, manipulating, and resolving DIDs
using the `did:bnb` method.

## Features
The `@identity.com/did-bnb-client` library provides the following features:

1. A W3C [DID core spec (v1.0)](https://www.w3.org/TR/did-core/) compliant DID method and resolver operating on the Binance Smart Chain (BSC).
2. TS Client for creating, manipulating, and resolving `did:bnb`.
3. Generic Support for VerificationMethods of any Type and Key length.
4. Native on-chain support for `EcdsaSecp256k1RecoveryMethod2020`.
5. A web-service driver, compatible with [uniresolver.io](https://unresolver.io) and [uniregistrar.io](https://uniregistrar.io).
6. Introduced `OWNERSHIP_PROOF` to indicate that a Verification Method Key signature was verified on-chain.
7. Introduced `DID_DOC_HIDDEN` flag that enables hiding a Verification Method from the DID resolution.

## Client library
### Installation
In the command line of the project folder, type the following and then press **Enter**:
```shell
yarn add @identity.com/did-bnb-client #
```

or

```shell
npm install @identity.com/did-bnb-client
```

### Contract Addresses
The BNB DID Registry contract is deployed at the following address (via proxy):
- Testnet: [0x88a05b4370BbB90c9F3EEa72A65c77131a7bc18d](https://testnet.bscscan.com/address/0x88a05b4370BbB90c9F3EEa72A65c77131a7bc18d)
- Mainnet: TODO

### Usage - Setup and Resolution
Create a service for a `did:bnb` by using the following code snippet:

#### Via Provider (read-only)
```typescript
const address = "0x88a05b4370BbB90c9F3EEa72A65c77131a7bc18d";
const provider = getDefaultProvider(process.env.RPC_URL); // e.g. https://bsc-testnet.publicnode.com
const chainEnv: ChainEnviroment = 'tesnet';
const didRegistry = new DidRegistry(provider, address, {chainEnvironment: 'localnet'});
// ... use didRegistry client
const randomDid = DidIdentifier.create(
Wallet.createRandom().address,
didRegistry.getDid().chainEnviroment
);
didRegistry.resolve(randomDid)
.then((didDocument) => {
console.log(didDocument);
})
.catch((error) => {
console.log(error);
});
```

#### Via Wallet
```typescript
const address = "0x88a05b4370BbB90c9F3EEa72A65c77131a7bc18d";
const provider = getDefaultProvider(process.env.RPC_URL); // e.g. https://bsc-testnet.publicnode.com
const randomWallet = Wallet.createRandom().connect(provider);
const chainEnv: ChainEnviroment = 'tesnet';
const didRegistry = new DidRegistry(randomWallet, address, {chainEnvironment: 'localnet'});
// ... use didRegistry client
// not passing a DID will resolve the DID of the wallet address
didRegistry.resolve()
.then((didDocument) => {
console.log(didDocument);
})
.catch((error) => {
console.log(error);
});
```
### DID resolution information
`did:bnb` DIDs are resolved in the following way:
1. `Generative` DIDs are DIDs that have no persisted DID account. (e.g. every valid EOA address is in this state).
This will return a generative DID document where only the public key of the Account is a valid Verification Method.
2. `Persisted` DIDs are DIDs that have a persisted DID account. Here the DID document represents the state that is found
on-chain.

### Check generative state (read-only)
```typescript
// can optionally take a DIDIdentifier as a parameter
const isGenerative: boolean = await didRegistry.isGenerativeDidState();
```

### Init a DID on-chain

```typescript
const tx: ContractTransaction = await didRegistry.initializeDidState();
```

### Add a VerificationMethod
This operation adds a new Verification Method to the DID. The `keyData` can be a generically sized `UInt8Array`, but logically it must match the `methodType` specified.

```typescript
const verificationMethod = {
fragment: 'test',
flags: reduceVmFlagArray([
BitwiseVerificationMethodFlag.CapabilityInvocation,
]),
methodType: VerificationMethodType.EcdsaSecp256k1RecoveryMethod2020,
keyData: utils.arrayify(Wallet.createRandom().address),
};
const tx: ContractTransaction = await didRegistry.addVerificationMethod(verificationMethod);
```

### Remove a VerificationMethod
This code removes a Verification Method with the given `fragment` from the DID. It is important to keep at least one valid Verification Method with a Capability Invocation flag to prevent a lockout.

```typescript
const tx: ContractTransaction = await didRegistry.removeVerificationMethod('test');
```

### Add a Service
This operation sets a new service on a DID. `serviceType` are strings, not enums, and can therefore be freely defined.

```typescript
const service = {
fragment: 'test2',
service_type: 'testType',
service_endpoint: 'testEndpoint',
};
const tx: ContractTransaction = await didRegistry.addService(service);
```

### Remove a Service
This operation removes a service with the given `fragment` name from the DID.

```typescript
const tx: ContractTransaction = await didRegistry.removeService('test2');
```

### Set VerificationMethodFlags
This sets/updates the flag on an existing VerificationMethod. **Important** if the flag contains `VerificationMethodFlags.OwnershipProof`
this transaction MUST use the same authority as the Verification Method. (e.g. proving that the owner can sign with
that specific VM).

```typescript
const tx: ContractTransaction = await didRegistry
.setVerificationMethodFlags('test', [
BitwiseVerificationMethodFlag.Authentication,
]);
```

### Add Native Controller (did:bnb - DID)
```typescript
const randomWallet = Wallet.createRandom();
const nativeController = DidIdentifier.create(
randomWallet.address,
didRegistry.getDid().chainEnviroment
);
const tx: ContractTransaction = await didRegistry
.addNativeController(nativeController);
```

### Add External Controller (non-did:bnb DID)
```typescript
const externalController = `did:ethr:${Wallet.createRandom().address}`;

const tx: ContractTransaction = await didRegistry
.addExternalController(externalController);
```

## Local Integration Test Setup
This repository uses `jest` to run integration test. These test will run against whatever `RPC_URL` is provided in the `.env` file.
This repository uses `test:integration` to run integration test. These test will run against whatever `RPC_URL` is provided in the `.env` file.

To run the integration test navigate to the `ts-client` directory and run `yarn jest`
To run the integration test navigate to the `ts-client` directory and run `yarn run test:integration`.

### Testing with Foundry
Foundry has a built in testnet node called `anvil`. You can first download foundry by following the [steps here](https://book.getfoundry.sh/getting-started/installation).
Expand Down
14 changes: 0 additions & 14 deletions ts-client/jest.config.ts

This file was deleted.

89 changes: 65 additions & 24 deletions ts-client/package.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,67 @@
{
"name": "did-bnb-ts-client",
"version": "1.0.0",
"main": "src/index.ts",
"license": "MIT",
"scripts": {
"generate-contract-types": "typechain --target=ethers-v6 ./abi/DIDRegistry.json",
"spawn-devnet": "tenderly devnet spawn-rpc --project project --template bnb-testnet",
"integration-test": "jest"
},
"dependencies": {
"dotenv": "^16.3.1",
"ethers": "^6.7.1"
},
"devDependencies": {
"@typechain/ethers-v6": "^0.5.0",
"@types/jest": "^29.5.4",
"@types/node": "^20.5.1",
"jest": "^29.6.3",
"tenderly": "^0.5.3",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typechain": "^8.3.1",
"typescript": "^5.1.6"
"name": "@identity.com/did-bnb-client",
"version": "1.0.0-beta.1",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
"license": "MIT",
"author": "Martin Riedel <[email protected]>",
"repository": "https://github.com/identity-com/did-bnb",
"homepage": "https://github.com/identity-com/did-bnb",
"files": [
"/dist",
"/npm-shrinkwrap.json"
],
"scripts": {
"postinstall": "$npm_execpath run generate-contract-types",
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check",
"clean": "shx rm -rf ./dist",
"compile": "tsc",
"build": "yarn clean && yarn compile",
"prepack": "yarn build",
"generate-contract-types": "typechain --target=ethers-v5 --out-dir ./src/contracts/typechain-types ./src/contracts/abi/DIDRegistry.json",
"spawn-devnet": "tenderly devnet spawn-rpc --project project --template bnb-testnet",
"test:integration": "ts-mocha test/integration/**/*.test.ts"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the github workflow for running the integration test calls the command npm run integration-test it need to be updated to this new command npm run test:integration.

https://github.com/identity-com/did-bnb/blob/main/.github/workflows/ts-client-integration-test.yml#L34

},
"dependencies": {
"@ethersproject/abi": "^5.7.0",
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/providers": "^5.7.2",
"bignumber.js": "^9.1.2",
"did-resolver": "^4.1.0",
"dotenv": "^16.3.1",
"ethers": "^5.7.2",
"ramda": "^0.29.0"
},
"devDependencies": {
"@typechain/ethers-v5": "^11.1.1",
"@types/chai": "^4.3.6",
"@types/chai-as-promised": "^7.1.6",
"@types/mocha": "^10.0.1",
"@types/node": "^20.5.1",
"@types/ramda": "^0.29.4",
"chai": "^4.3.8",
"chai-as-promised": "^7.1.1",
"husky": "^8.0.3",
"mocha": "^10.0.0",
"nyc": "^15.1.0",
"prettier": "^3.0.3",
"shx": "^0.3.4",
"tenderly": "^0.5.3",
"ts-mocha": "^10.0.0",
"ts-node": "^10.9.1",
"typechain": "^8.3.1",
"typescript": "^5.1.6"
},
"husky": {
"hooks": {
"pre-commit": "yarn lint"
}
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
}
}
2 changes: 2 additions & 0 deletions ts-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './service';
export * from './utils';
Loading