Skip to content

Commit

Permalink
cloud wallet web storage
Browse files Browse the repository at this point in the history
  • Loading branch information
maycon-mello committed Sep 24, 2024
1 parent 17a777f commit beca5cc
Show file tree
Hide file tree
Showing 37 changed files with 1,176 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/core/src/cloud-wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export async function initializeCloudWallet({
async function clearEdvDocuments() {
const allDocs = await storageInterface.find({});

debugger;
for (const doc of allDocs.documents) {
await storageInterface.delete({document: doc});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import {LocalStorage} from '@docknetwork/wallet-sdk-data-store/src/types';
import assert from 'assert';

export type LocalStorage = {
getItem: (key: string) => Promise<string | null>;
setItem: (key: string, value: string) => Promise<void>;
removeItem: (key: string) => Promise<void>;
};

let _localStorage: LocalStorage;

/**
Expand Down
4 changes: 2 additions & 2 deletions packages/data-store-typeorm/src/migrations-data-source.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {getDataSource} from './helpers';
import {createDataSource} from './helpers';

export default getDataSource({
export default createDataSource({
dbType: 'sqlite',
databasePath: 'data-store.sqlite',
});
3 changes: 3 additions & 0 deletions packages/data-store-web/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*.sqlite
lib/
tsconfig.build.tsbuildinfo
2 changes: 2 additions & 0 deletions packages/data-store-web/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
sqlite/
21 changes: 21 additions & 0 deletions packages/data-store-web/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module.exports = {
testEnvironment: 'node',
testTimeout: 30000,
testMatch: [
"<rootDir>/src/**/!(*.e2e).test.ts"
],
coverageThreshold: {
global: {
branches: 10,
functions: 10,
lines: 10,
statements: 10,
},
},
transform: {
'^.+\\.ts$': 'ts-jest',
},
resetMocks: false,
setupFilesAfterEnv: ['<rootDir>/setup-tests.ts'],
setupFiles: ['jest-localstorage-mock'],
};
32 changes: 32 additions & 0 deletions packages/data-store-web/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@docknetwork/wallet-sdk-data-store-web",
"version": "0.4.19",
"license": "https://github.com/docknetwork/react-native-sdk/LICENSE",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/docknetwork/react-native-sdk",
"directory": "packages/data-store"
},
"scripts": {
"test": "jest",
"build": "tsc -p tsconfig.build.json"
},
"peerDependencies": {
"typeorm": "^0.3.15"
},
"dependencies": {
"@docknetwork/wallet-sdk-wasm": "^0.4.19",
"uuid": "^8.3.2"
},
"devDependencies": {
"jest": "29.1.0",
"ts-jest": "29.1.0",
"ts-node": "^10.9.1",
"typescript": "^5.0.4",
"typeorm": "^0.3.15",
"sqlite3": "^5.0.2",
"reflect-metadata": "^0.1.13"
}
}
3 changes: 3 additions & 0 deletions packages/data-store-web/scripts/publish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
yarn build
npm publish --access public

Empty file.
56 changes: 56 additions & 0 deletions packages/data-store-web/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import {
createTestDataStore,
createV1EmptyDataStore,
setupV1MockDataStore,
} from '../../test/test-utils';
import {getV1LocalStorage} from '../migration/migration1/v1-data-store';
import {CURRENT_DATA_STORE_VERSION} from '../migration';
import {DataStore} from '../types';
import {WalletEntity, getWallet} from '../entities/wallet.entity';
import {closeDataStore} from '../index';

describe('Data store', () => {
describe('v2-data-store migration', () => {
let dataStore: DataStore;

beforeAll(async () => {
await setupV1MockDataStore();
dataStore = await createTestDataStore();
});

it('should remove wallet json from local storage', async () => {
const jsonData = await getV1LocalStorage().getItem('wallet');
expect(jsonData).toBeUndefined();
});

it('should create DataStoreConfigs', async () => {
const configs = await getWallet({dataStore});
expect(configs).toBeDefined();
expect(configs.networkId).toBe('mainnet');
expect(configs.version).toBe(CURRENT_DATA_STORE_VERSION);
});

afterAll(() => {
closeDataStore(dataStore);
});
});

describe('empty wallet migration', () => {
let dataStore: DataStore;

beforeAll(async () => {
await createV1EmptyDataStore();
dataStore = await createTestDataStore();
});

it('should create SDKConfigs', async () => {
const configs = await getWallet({dataStore});
expect(configs.networkId).toBe('mainnet');
expect(configs.version).toBe(CURRENT_DATA_STORE_VERSION);
});

afterAll(() => {
closeDataStore(dataStore);
});
});
});
24 changes: 24 additions & 0 deletions packages/data-store-web/src/__tests__/v1-data-store.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {setupV1MockDataStore} from '../../test/test-utils';
import {
getV1LocalStorage,
getWalletDocuments,
} from '../migration/migration1/v1-data-store';
import _walletJSON from '../../test/wallet.json';

describe('v2-data-store', () => {
beforeAll(async () => {
await setupV1MockDataStore();
});

it('should have access to v2 localStorage', async () => {
const jsonData = await getV1LocalStorage().getItem('wallet');
expect(jsonData).toBeDefined();
const wallet = JSON.parse(jsonData as string);
expect(wallet).toStrictEqual(_walletJSON);
});

it('should be able to fetch v2 documents', async () => {
const documents = await getWalletDocuments();
expect(documents.length).toBeGreaterThan(1);
});
});
82 changes: 82 additions & 0 deletions packages/data-store-web/src/entities/document/create-document.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
ContextProps,
DataStoreEvents,
WalletDocument,
} from '@docknetwork/wallet-sdk-data-store/src/types';
import {v4 as uuid} from 'uuid';
import {DocumentEntity} from './document.entity';
import {getDocumentById} from './get-document-by-id';
import {logger} from '@docknetwork/wallet-sdk-data-store/src/logger';
import {localStorageJSON} from '../../localStorageJSON';
import {getAllDocuments} from './get-all-documents';

export async function appendDocument(document: WalletDocument) {
const entities = (await localStorageJSON.getItem('documents')) || [];

await localStorageJSON.setItem('documents', [...entities, document]);
}

/**
* Create document
* @param dataStore
* @param json
*/
export async function createDocument({
dataStore,
json,
options,
}: ContextProps & {
json: any;
options?: any;
}): Promise<WalletDocument> {
logger.debug(`Creating document with id ${json.id}...`);
if (json.id) {
const existingDocument = await getDocumentById({
dataStore,
id: json.id,
});

if (existingDocument) {
logger.debug(`Document with id ${json.id} already exists`);
throw new Error(`Document with id ${json.id} already exists`);
}
}

if (!json.id) {
json.id = uuid();
}

let networkId;

if (json._networkId) {
networkId = json._networkId;
delete json._networkId;
} else {
const resolution = await dataStore.resolveDocumentNetwork({
document: json,
dataStore,
});

networkId = resolution.networkId || dataStore.networkId;
}

const entity: DocumentEntity = {
networkId,
id: json.id,
type: json.type,
correlation: json.correlation || [],
data: json,
};

appendDocument(entity);

if (!options?.stopPropagation) {
dataStore.events.emit(DataStoreEvents.DocumentCreated, json);
} else {
console.log('stopPropagation is true');
}

logger.debug(`Document added to the wallet`);

return entity;
}
135 changes: 135 additions & 0 deletions packages/data-store-web/src/entities/document/decument.entity.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import {DocumentEntity} from './document.entity';
import {createTestDataStore} from '../../../test/test-utils';
import {DataStore} from '../../types';
import {createDocument} from './create-document';
import {getDocumentsByType} from './get-documens-by-type';
import {getDocumentById} from './get-document-by-id';
import {getDocumentCorrelations} from './get-document-correlations';

const mockDocuments = [
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://www.w3.org/2018/credentials/examples/v1',
],
id: 'http://example.gov/credentials/test',
type: ['VerifiableCredential', 'UniversityDegreeCredential'],
issuer: {
id: 'did:example:123456789abcdefghi',
},
issuanceDate: '2020-03-10T04:24:12.164Z',
credentialSubject: {
id: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
degree: {
type: 'BachelorDegree',
name: 'Bachelor of Science and Arts',
},
},
},
{
'@context': [
'https://www.w3.org/2018/credentials/v1',
'https://www.w3.org/2018/credentials/examples/v1',
],
id: 'http://example.gov/credentials/test2',
type: ['VerifiableCredential', 'BasicCredential'],
issuer: {
id: 'did:example:123456789abcdefghi',
},
issuanceDate: '2020-03-10T04:24:12.164Z',
credentialSubject: {
id: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
name: 'Testing',
},
},
{
'@context': ['https://w3id.org/wallet/v1'],
id: 'urn:uuid:c410e44a-9525-11ea-bb37-0242ac130002',
name: 'My Ropsten Mnemonic 1',
image: 'https://via.placeholder.com/150',
description: 'For testing only, totally compromised.',
tags: ['professional', 'organization', 'compromised'],
correlation: [],
type: 'Mnemonic',
value:
'humble piece toy mimic miss hurdle smile awkward patch drama hurry mixture',
},
{
'@context': ['https://w3id.org/wallet/v1'],
id: 'c47f3ed0-b4b5-4983-8962-759196fd3ece',
type: 'Currency',
value: 0,
symbol: 'DOCK',
},
{
'@context': ['https://w3id.org/wallet/v1'],
id: '37NKEP14n9omsAgxJ3sn14XtHo2vs5a34UcpCyybXQJoUQ92',
type: 'Address',
value: '37NKEP14n9omsAgxJ3sn14XtHo2vs5a34UcpCyybXQJoUQ92',
address: '37NKEP14n9omsAgxJ3sn14XtHo2vs5a34UcpCyybXQJoUQ92',
name: 'Test',
correlation: [
'urn:uuid:c410e44a-9525-11ea-bb37-0242ac130002',
'c47f3ed0-b4b5-4983-8962-759196fd3ece',
],
},
];

describe('DocumentEntity', () => {
let dataStore: DataStore;

beforeAll(async () => {
dataStore = await createTestDataStore();

for (const document of mockDocuments) {
await createDocument({
dataStore,
json: document,
});
}
});

it('should be able to find a document by id', async () => {
const mockData = mockDocuments[0];
const document = await getDocumentById({
dataStore,
id: mockData.id,
});
expect(document).toBeDefined();
expect(document.type).toEqual(mockData.type);
});

describe('getDocumentsByType', () => {
it('should be able to query all VerifiableCredential', async () => {
const documents = await getDocumentsByType({
dataStore,
type: 'VerifiableCredential',
});

expect(documents).toBeDefined();
expect(documents.length).toEqual(2);
});

it('should be able query only BasicCredential', async () => {
const documents = await getDocumentsByType({
dataStore,
type: 'BasicCredential',
});

expect(documents).toBeDefined();
expect(documents.length).toEqual(1);
});
});

describe('getDocumentCorrelations', () => {
it('expect to query all correlations', async () => {
const documents = await getDocumentCorrelations({
dataStore,
documentId: '37NKEP14n9omsAgxJ3sn14XtHo2vs5a34UcpCyybXQJoUQ92',
});

expect(documents).toBeDefined();
expect(documents.length).toEqual(2);
});
});
});
Loading

0 comments on commit beca5cc

Please sign in to comment.