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

Added private key export RPC method #35

Merged
merged 13 commits into from
Feb 9, 2024
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- `@rarimo/rarime`:
- `RemoveCredentials` credentials RPC method
- `ExportIdentity` RPC method

## [2.0.3] - 2024-02-06
### Changed
Expand Down
7 changes: 7 additions & 0 deletions packages/connector/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ createIdentity(): Promise<string>
```
Returns DID.

### Export identity
To export your identity you need to call this method:
```typescript
ExportIdentity(): Promise<string>
```
Show Your identity private key in metamask dialog.

### Save Verifiable Credentials
To save Verifiable Credentials you need to call this method with params:
```typescript
Expand Down
9 changes: 9 additions & 0 deletions packages/connector/src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,12 @@ export const getCredentials = async function (
this.snapId,
);
};

export const exportIdentity = async function (
this: MetamaskSnap,
): Promise<void> {
return await sendSnapMethod(
{ method: RPCMethods.ExportIdentity },
this.snapId,
);
};
2 changes: 2 additions & 0 deletions packages/connector/src/snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getCredentials,
checkCredentialExistence,
removeCredentials,
exportIdentity,
} from './methods';

export class MetamaskSnap {
Expand All @@ -25,6 +26,7 @@ export class MetamaskSnap {
checkStateContractSync: checkStateContractSync.bind(this),
getCredentials: getCredentials.bind(this),
checkCredentialExistence: checkCredentialExistence.bind(this),
exportIdentity: exportIdentity.bind(this),
};
};
}
2 changes: 2 additions & 0 deletions packages/connector/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum RPCMethods {
CreateProof = 'create_proof',
CheckStateContractSync = 'check_state_contract_sync',
GetCredentials = 'get_credentials',
ExportIdentity = 'export_identity',
}

export type SaveCredentialsResponse = Pick<W3CCredential, 'type'> &
Expand All @@ -35,6 +36,7 @@ export type SnapConnector = {
checkCredentialExistence(
params: CheckCredentialExistenceRequestParams,
): Promise<SaveCredentialsResponse[]>;
exportIdentity(): Promise<void>;
};

export type GetSnapsResponse = {
Expand Down
12 changes: 12 additions & 0 deletions packages/snap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ await window.ethereum.request({
});
```

### Export identity
To export an identity you need to call this method:
```javascript
await window.ethereum.request({
method: 'wallet_invokeSnap',
params: {
snapId: 'snapId',
request: { method: 'export_identity' },
},
});
```

### Save Verifiable Credentials
To save Verifiable Credentials you need to call this method with params:
```javascript
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"url": "https://github.com/rarimo/rarime.git"
},
"source": {
"shasum": "EIrkj4xYKTrYUvN7OBR5gyFBFK8+QBrpuGYIjNmk3GU=",
"shasum": "NIhA12lav6/aMeUbLmleCW90iyCfyPXinWkXx1ehBgk=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/snap/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ export const SUPPORTED_CHAINS: Record<number, ChainInfo> = {
},
};

export const GET_CREDENTIALS_SUPPORTED_HOSTNAMES = [
export const HOSTNAMES_WHITELIST = [
// Local
'localhost',
// Staging
'dashboard.stage.rarime.com',
'app.staging.rarime.com',
'app.stage.rarime.com',
// Production
'dashboard.rarime.com',
'app.rarime.com',
Expand Down
6 changes: 5 additions & 1 deletion packages/snap/src/helpers/common-helpers.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { providers } from 'ethers';
import { config, SUPPORTED_CHAINS } from '../config';
import { config, HOSTNAMES_WHITELIST, SUPPORTED_CHAINS } from '../config';
import { ChainInfo } from '../types';

export const getChainInfo = (chainId: number): ChainInfo => {
Expand Down Expand Up @@ -38,6 +38,10 @@ export const getHostname = (origin: string): string => {
return new URL(origin).hostname;
};

export const isOriginInWhitelist = (origin: string) => {
return HOSTNAMES_WHITELIST.includes(getHostname(origin));
};

export const uniqBy = (arr: any[], predicate: string) => {
return [
...arr
Expand Down
30 changes: 27 additions & 3 deletions packages/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ import {
checkIfStateSynced,
getClaimIdFromVCId,
getCoreOperationByIndex,
getHostname,
getProviderChainInfo,
getRarimoCoreUrl,
isDidSupported,
isOriginInWhitelist,
loadDataFromRarimoCore,
migrateVCsToLastCeramicModel,
parseDidV2,
Expand All @@ -45,7 +45,6 @@ import {
isValidCreateProofRequest,
isValidSaveCredentialsOfferRequest,
} from './typia-generated';
import { GET_CREDENTIALS_SUPPORTED_HOSTNAMES } from './config';

export const onRpcRequest = async ({
request,
Expand Down Expand Up @@ -429,7 +428,7 @@ export const onRpcRequest = async ({
}

case RPCMethods.GetCredentials: {
if (!GET_CREDENTIALS_SUPPORTED_HOSTNAMES.includes(getHostname(origin))) {
if (!isOriginInWhitelist(origin)) {
throw new Error('This origin does not have access to credentials');
}

Expand All @@ -438,6 +437,31 @@ export const onRpcRequest = async ({
return await vcManager.getAllDecryptedVCs();
}

case RPCMethods.ExportIdentity: {
if (!isOriginInWhitelist(origin)) {
throw new Error('This origin does not have access to export identity');
}

const identityStorage = await getItemFromStore(StorageKeys.identity);

if (!identityStorage.privateKeyHex) {
throw new Error('Identity not created');
}

return snap.request({
method: 'snap_dialog',
params: {
type: 'alert',
content: panel([
heading('Your RariMe private key'),
divider(),
text('Сopy:'),
copyable(identityStorage.privateKeyHex),
]),
},
});
}

default:
throw new Error('Method not found.');
}
Expand Down
Loading
Loading