@docknetwork/wallet-sdk-data-store 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +39 -0
- package/jest.config.ts +21 -0
- package/lib/configs.d.ts +3 -0
- package/lib/configs.d.ts.map +1 -0
- package/lib/configs.js +30 -0
- package/lib/configs.js.map +1 -0
- package/lib/document-network-resolver.d.ts +3 -0
- package/lib/document-network-resolver.d.ts.map +1 -0
- package/lib/document-network-resolver.js +52 -0
- package/lib/document-network-resolver.js.map +1 -0
- package/lib/entities/document/create-document.d.ts +10 -0
- package/lib/entities/document/create-document.d.ts.map +1 -0
- package/lib/entities/document/create-document.js +111 -0
- package/lib/entities/document/create-document.js.map +1 -0
- package/lib/entities/document/document.entity.d.ts +11 -0
- package/lib/entities/document/document.entity.d.ts.map +1 -0
- package/lib/entities/document/document.entity.js +55 -0
- package/lib/entities/document/document.entity.js.map +1 -0
- package/lib/entities/document/get-all-documents.d.ts +11 -0
- package/lib/entities/document/get-all-documents.d.ts.map +1 -0
- package/lib/entities/document/get-all-documents.js +78 -0
- package/lib/entities/document/get-all-documents.js.map +1 -0
- package/lib/entities/document/get-documens-by-type.d.ts +10 -0
- package/lib/entities/document/get-documens-by-type.d.ts.map +1 -0
- package/lib/entities/document/get-documens-by-type.js +71 -0
- package/lib/entities/document/get-documens-by-type.js.map +1 -0
- package/lib/entities/document/get-document-by-id.d.ts +13 -0
- package/lib/entities/document/get-document-by-id.d.ts.map +1 -0
- package/lib/entities/document/get-document-by-id.js +92 -0
- package/lib/entities/document/get-document-by-id.js.map +1 -0
- package/lib/entities/document/get-document-correlations.d.ts +10 -0
- package/lib/entities/document/get-document-correlations.d.ts.map +1 -0
- package/lib/entities/document/get-document-correlations.js +78 -0
- package/lib/entities/document/get-document-correlations.js.map +1 -0
- package/lib/entities/document/helpers.d.ts +30 -0
- package/lib/entities/document/helpers.d.ts.map +1 -0
- package/lib/entities/document/helpers.js +196 -0
- package/lib/entities/document/helpers.js.map +1 -0
- package/lib/entities/document/index.d.ts +10 -0
- package/lib/entities/document/index.d.ts.map +1 -0
- package/lib/entities/document/index.js +26 -0
- package/lib/entities/document/index.js.map +1 -0
- package/lib/entities/document/remove-document.d.ts +15 -0
- package/lib/entities/document/remove-document.d.ts.map +1 -0
- package/lib/entities/document/remove-document.js +94 -0
- package/lib/entities/document/remove-document.js.map +1 -0
- package/lib/entities/document/update-document.d.ts +10 -0
- package/lib/entities/document/update-document.d.ts.map +1 -0
- package/lib/entities/document/update-document.js +72 -0
- package/lib/entities/document/update-document.js.map +1 -0
- package/lib/entities/document-type.entity.d.ts +6 -0
- package/lib/entities/document-type.entity.d.ts.map +1 -0
- package/lib/entities/document-type.entity.js +32 -0
- package/lib/entities/document-type.entity.js.map +1 -0
- package/lib/entities/log.entity.d.ts +15 -0
- package/lib/entities/log.entity.d.ts.map +1 -0
- package/lib/entities/log.entity.js +108 -0
- package/lib/entities/log.entity.js.map +1 -0
- package/lib/entities/network.entity.d.ts +6 -0
- package/lib/entities/network.entity.d.ts.map +1 -0
- package/lib/entities/network.entity.js +35 -0
- package/lib/entities/network.entity.js.map +1 -0
- package/lib/entities/transaction.entity.d.ts +24 -0
- package/lib/entities/transaction.entity.d.ts.map +1 -0
- package/lib/entities/transaction.entity.js +139 -0
- package/lib/entities/transaction.entity.js.map +1 -0
- package/lib/entities/wallet.entity.d.ts +10 -0
- package/lib/entities/wallet.entity.d.ts.map +1 -0
- package/lib/entities/wallet.entity.js +109 -0
- package/lib/entities/wallet.entity.js.map +1 -0
- package/lib/helpers.d.ts +6 -0
- package/lib/helpers.d.ts.map +1 -0
- package/lib/helpers.js +98 -0
- package/lib/helpers.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +145 -0
- package/lib/index.js.map +1 -0
- package/lib/logger.d.ts +14 -0
- package/lib/logger.d.ts.map +1 -0
- package/lib/logger.js +40 -0
- package/lib/logger.js.map +1 -0
- package/lib/migration/bootstrap-tables.d.ts +3 -0
- package/lib/migration/bootstrap-tables.d.ts.map +1 -0
- package/lib/migration/bootstrap-tables.js +8 -0
- package/lib/migration/bootstrap-tables.js.map +1 -0
- package/lib/migration/index.d.ts +8 -0
- package/lib/migration/index.d.ts.map +1 -0
- package/lib/migration/index.js +132 -0
- package/lib/migration/index.js.map +1 -0
- package/lib/migration/migration1/index.d.ts +16 -0
- package/lib/migration/migration1/index.d.ts.map +1 -0
- package/lib/migration/migration1/index.js +110 -0
- package/lib/migration/migration1/index.js.map +1 -0
- package/lib/migration/migration1/migrate-v1-data.d.ts +8 -0
- package/lib/migration/migration1/migrate-v1-data.d.ts.map +1 -0
- package/lib/migration/migration1/migrate-v1-data.js +171 -0
- package/lib/migration/migration1/migrate-v1-data.js.map +1 -0
- package/lib/migration/migration1/v1-data-store.d.ts +15 -0
- package/lib/migration/migration1/v1-data-store.d.ts.map +1 -0
- package/lib/migration/migration1/v1-data-store.js +80 -0
- package/lib/migration/migration1/v1-data-store.js.map +1 -0
- package/lib/migrations/1691498362273-bootstrap.d.ts +7 -0
- package/lib/migrations/1691498362273-bootstrap.d.ts.map +1 -0
- package/lib/migrations/1691498362273-bootstrap.js +178 -0
- package/lib/migrations/1691498362273-bootstrap.js.map +1 -0
- package/lib/migrations/index.d.ts +4 -0
- package/lib/migrations/index.d.ts.map +1 -0
- package/lib/migrations/index.js +5 -0
- package/lib/migrations/index.js.map +1 -0
- package/lib/migrations-data-source.d.ts +3 -0
- package/lib/migrations-data-source.d.ts.map +1 -0
- package/lib/migrations-data-source.js +8 -0
- package/lib/migrations-data-source.js.map +1 -0
- package/lib/typeorm.d.ts +2 -0
- package/lib/typeorm.d.ts.map +1 -0
- package/lib/typeorm.js +18 -0
- package/lib/typeorm.js.map +1 -0
- package/lib/types.d.ts +49 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +3 -0
- package/lib/types.js.map +1 -0
- package/package.json +31 -0
- package/scripts/publish.sh +3 -0
- package/setup-tests.ts +0 -0
- package/src/__tests__/index.test.ts +56 -0
- package/src/__tests__/v1-data-store.test.ts +24 -0
- package/src/configs.ts +28 -0
- package/src/document-network-resolver.ts +19 -0
- package/src/entities/document/create-document.ts +72 -0
- package/src/entities/document/decument.entity.test.ts +135 -0
- package/src/entities/document/document.entity.ts +40 -0
- package/src/entities/document/get-all-documents.ts +39 -0
- package/src/entities/document/get-documens-by-type.ts +30 -0
- package/src/entities/document/get-document-by-id.ts +45 -0
- package/src/entities/document/get-document-correlations.ts +34 -0
- package/src/entities/document/helpers.ts +115 -0
- package/src/entities/document/index.ts +9 -0
- package/src/entities/document/remove-document.ts +34 -0
- package/src/entities/document/update-document.ts +25 -0
- package/src/entities/document-type.entity.ts +11 -0
- package/src/entities/log.entity.ts +46 -0
- package/src/entities/network.entity.ts +14 -0
- package/src/entities/transaction.entity.ts +67 -0
- package/src/entities/wallet.entity.ts +37 -0
- package/src/helpers.ts +52 -0
- package/src/index.ts +83 -0
- package/src/logger.ts +37 -0
- package/src/migration/bootstrap-tables.ts +5 -0
- package/src/migration/index.ts +53 -0
- package/src/migration/migration1/index.ts +64 -0
- package/src/migration/migration1/migrate-v1-data.ts +57 -0
- package/src/migration/migration1/v1-data-store.ts +39 -0
- package/src/migrations/1691498362273-bootstrap.ts +130 -0
- package/src/migrations/index.ts +3 -0
- package/src/migrations-data-source.ts +6 -0
- package/src/typeorm.ts +1 -0
- package/src/types.ts +67 -0
- package/test/mock-local-storage.ts +17 -0
- package/test/test-utils.ts +23 -0
- package/test/wallet.json +209 -0
- package/tsconfig.build.json +25 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import assert from 'assert';
|
|
2
|
+
import {ContextProps} from '../../types';
|
|
3
|
+
import {DocumentEntity} from './document.entity';
|
|
4
|
+
import { logger } from '../../logger';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Remove document
|
|
8
|
+
* @param dataStore
|
|
9
|
+
* @param id
|
|
10
|
+
*/
|
|
11
|
+
export async function removeDocument({
|
|
12
|
+
dataStore,
|
|
13
|
+
id,
|
|
14
|
+
}: ContextProps & {id: string}): Promise<void> {
|
|
15
|
+
assert(!!id, 'Document id is required');
|
|
16
|
+
|
|
17
|
+
logger.debug(`Removing document with id ${id}`);
|
|
18
|
+
const repository = dataStore.db.getRepository(DocumentEntity);
|
|
19
|
+
await repository.delete({
|
|
20
|
+
id,
|
|
21
|
+
networkId: dataStore.networkId,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Remove all documents
|
|
27
|
+
* @param dataStore
|
|
28
|
+
*/
|
|
29
|
+
export async function removeAllDocuments({
|
|
30
|
+
dataStore,
|
|
31
|
+
}: ContextProps): Promise<void> {
|
|
32
|
+
const repository = dataStore.db.getRepository(DocumentEntity);
|
|
33
|
+
await repository.delete({});
|
|
34
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ContextProps, WalletDocument } from '../../types';
|
|
2
|
+
import { saveOptions, toDocumentEntity } from './helpers';
|
|
3
|
+
import { DocumentEntity } from './document.entity';
|
|
4
|
+
import { logger } from '../../logger';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Update document
|
|
8
|
+
* @param dataStore
|
|
9
|
+
* @param document
|
|
10
|
+
*/
|
|
11
|
+
export async function updateDocument({
|
|
12
|
+
dataStore,
|
|
13
|
+
document,
|
|
14
|
+
}: ContextProps & {document: WalletDocument}): Promise<WalletDocument> {
|
|
15
|
+
logger.debug(`Updating document with id ${document.id}`);
|
|
16
|
+
|
|
17
|
+
const repository = dataStore.db.getRepository(DocumentEntity);
|
|
18
|
+
const entity = await toDocumentEntity({
|
|
19
|
+
dataStore,
|
|
20
|
+
document,
|
|
21
|
+
});
|
|
22
|
+
await repository.save(entity, saveOptions);
|
|
23
|
+
|
|
24
|
+
return document;
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {Entity, Column, PrimaryColumn, ManyToMany} from '../typeorm';
|
|
2
|
+
import {DocumentEntity} from './document/document.entity';
|
|
3
|
+
|
|
4
|
+
@Entity()
|
|
5
|
+
export class DocumentTypeEntity {
|
|
6
|
+
@PrimaryColumn('text')
|
|
7
|
+
id: string;
|
|
8
|
+
|
|
9
|
+
@ManyToMany(() => DocumentEntity, document => document._typeRel)
|
|
10
|
+
documents: DocumentEntity[];
|
|
11
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import {Entity, Column, PrimaryColumn} from '../typeorm';
|
|
2
|
+
import {ContextProps, DataStore} from '../types';
|
|
3
|
+
|
|
4
|
+
@Entity()
|
|
5
|
+
export class LogEntity {
|
|
6
|
+
@PrimaryColumn()
|
|
7
|
+
id: string;
|
|
8
|
+
|
|
9
|
+
@Column()
|
|
10
|
+
level: string;
|
|
11
|
+
|
|
12
|
+
@Column()
|
|
13
|
+
value: string;
|
|
14
|
+
|
|
15
|
+
@Column()
|
|
16
|
+
createdAt: Date;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export async function getLogs({
|
|
20
|
+
dataStore,
|
|
21
|
+
}: {
|
|
22
|
+
dataStore: DataStore;
|
|
23
|
+
}): Promise<LogEntity[]> {
|
|
24
|
+
const repository = dataStore.db.getRepository(LogEntity);
|
|
25
|
+
const entities = await repository.find({
|
|
26
|
+
order: {
|
|
27
|
+
createdAt: 'DESC',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return entities;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export async function createLog({
|
|
35
|
+
dataStore,
|
|
36
|
+
log,
|
|
37
|
+
}: {
|
|
38
|
+
dataStore: DataStore;
|
|
39
|
+
log: LogEntity,
|
|
40
|
+
}): Promise<LogEntity> {
|
|
41
|
+
const repository = dataStore.db.getRepository(LogEntity);
|
|
42
|
+
|
|
43
|
+
log.createdAt = new Date();
|
|
44
|
+
|
|
45
|
+
return repository.save(log);
|
|
46
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Entity, Column, PrimaryColumn } from 'typeorm';
|
|
2
|
+
import { DataStore } from '../types';
|
|
3
|
+
|
|
4
|
+
@Entity()
|
|
5
|
+
export class TransactionEntity {
|
|
6
|
+
@PrimaryColumn()
|
|
7
|
+
id: string;
|
|
8
|
+
|
|
9
|
+
@Column({ nullable: true })
|
|
10
|
+
hash: string;
|
|
11
|
+
|
|
12
|
+
@Column({ default: 'transfer' })
|
|
13
|
+
type: string;
|
|
14
|
+
|
|
15
|
+
@Column({ nullable: true })
|
|
16
|
+
error: string;
|
|
17
|
+
|
|
18
|
+
@Column({ nullable: true })
|
|
19
|
+
metadata: string;
|
|
20
|
+
|
|
21
|
+
@Column()
|
|
22
|
+
date: Date;
|
|
23
|
+
|
|
24
|
+
@Column()
|
|
25
|
+
fromAddress: string;
|
|
26
|
+
|
|
27
|
+
@Column()
|
|
28
|
+
recipientAddress: string;
|
|
29
|
+
|
|
30
|
+
@Column({ nullable: true })
|
|
31
|
+
amount: string;
|
|
32
|
+
|
|
33
|
+
@Column()
|
|
34
|
+
feeAmount: string;
|
|
35
|
+
|
|
36
|
+
@Column({ default: 'testnet' })
|
|
37
|
+
network: string;
|
|
38
|
+
|
|
39
|
+
@Column()
|
|
40
|
+
status: string;
|
|
41
|
+
|
|
42
|
+
@Column({ default: false })
|
|
43
|
+
retrySucceeded: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function getLogs({
|
|
47
|
+
dataStore,
|
|
48
|
+
}: {
|
|
49
|
+
dataStore: DataStore;
|
|
50
|
+
}): Promise<TransactionEntity[]> {
|
|
51
|
+
const repository = dataStore.db.getRepository(TransactionEntity);
|
|
52
|
+
const entities = await repository.find({});
|
|
53
|
+
|
|
54
|
+
return entities;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function createTransaction({
|
|
58
|
+
dataStore,
|
|
59
|
+
transaction,
|
|
60
|
+
}: {
|
|
61
|
+
dataStore: DataStore;
|
|
62
|
+
transaction: TransactionEntity,
|
|
63
|
+
}): Promise<TransactionEntity> {
|
|
64
|
+
const repository = dataStore.db.getRepository(TransactionEntity);
|
|
65
|
+
|
|
66
|
+
return repository.save(transaction);
|
|
67
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {Entity, Column, PrimaryGeneratedColumn, PrimaryColumn} from '../typeorm';
|
|
2
|
+
import {ContextProps} from '../types';
|
|
3
|
+
|
|
4
|
+
@Entity()
|
|
5
|
+
export class WalletEntity {
|
|
6
|
+
@PrimaryColumn()
|
|
7
|
+
id: string;
|
|
8
|
+
|
|
9
|
+
@Column({
|
|
10
|
+
nullable: true,
|
|
11
|
+
})
|
|
12
|
+
version?: string;
|
|
13
|
+
|
|
14
|
+
@Column()
|
|
15
|
+
networkId: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export async function getWallet({
|
|
19
|
+
dataStore,
|
|
20
|
+
}: ContextProps): Promise<WalletEntity> {
|
|
21
|
+
const result = await dataStore.db.getRepository(WalletEntity).find();
|
|
22
|
+
return result[0];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function createWallet({dataStore}: ContextProps): Promise<WalletEntity> {
|
|
26
|
+
return dataStore.db.getRepository(WalletEntity).save({
|
|
27
|
+
id: 'configs',
|
|
28
|
+
...dataStore,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function updateWallet({dataStore}: ContextProps): Promise<WalletEntity> {
|
|
33
|
+
return dataStore.db.getRepository(WalletEntity).save({
|
|
34
|
+
id: 'configs',
|
|
35
|
+
...dataStore,
|
|
36
|
+
});
|
|
37
|
+
}
|
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import {DataSource} from './typeorm';
|
|
2
|
+
// import {SDKConfigsEntity} from './entities/data-store-configs.entity';
|
|
3
|
+
import {logger} from './logger';
|
|
4
|
+
import {DataStoreConfigs} from './types';
|
|
5
|
+
import {NetworkEntity} from './entities/network.entity';
|
|
6
|
+
import {DocumentEntity} from './entities/document/document.entity';
|
|
7
|
+
import {DocumentTypeEntity} from './entities/document-type.entity';
|
|
8
|
+
import {WalletEntity} from './entities/wallet.entity';
|
|
9
|
+
import typeOrmMigrations from './migrations';
|
|
10
|
+
import { LogEntity } from './entities/log.entity';
|
|
11
|
+
import { TransactionEntity } from './entities/transaction.entity';
|
|
12
|
+
|
|
13
|
+
export function documentHasType(document: any, type: string) {
|
|
14
|
+
if (Array.isArray(document.type)) {
|
|
15
|
+
return document.type.includes(type);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return document.type === type;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getDataSource(options: DataStoreConfigs) {
|
|
22
|
+
const dataSource = new DataSource({
|
|
23
|
+
type: (options.dbType as any) || 'sqlite',
|
|
24
|
+
database: options.databasePath,
|
|
25
|
+
entities: [WalletEntity, NetworkEntity, DocumentEntity, DocumentTypeEntity],
|
|
26
|
+
synchronize: process.env.NODE_ENV === 'test',
|
|
27
|
+
dropSchema: options.dropSchema,
|
|
28
|
+
driver: options.driver,
|
|
29
|
+
sqlJsConfig: options.sqlJsConfig,
|
|
30
|
+
migrationsRun: process.env.NODE_ENV !== 'test',
|
|
31
|
+
migrations: typeOrmMigrations,
|
|
32
|
+
...(options.typeORMConfigs || {}),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
return dataSource;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export async function initializeTypeORM(options: DataStoreConfigs) {
|
|
39
|
+
const dataSource = getDataSource(options);
|
|
40
|
+
|
|
41
|
+
await dataSource
|
|
42
|
+
.initialize()
|
|
43
|
+
.then(() => {
|
|
44
|
+
logger.debug('Data Source initialized successfully');
|
|
45
|
+
})
|
|
46
|
+
.catch(err => {
|
|
47
|
+
logger.error(`Error during Data Source initialization: ${err}`);
|
|
48
|
+
throw err;
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return dataSource;
|
|
52
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {initializeTypeORM} from './helpers';
|
|
2
|
+
import {DataStore, DataStoreConfigs} from './types';
|
|
3
|
+
import {migrate} from './migration';
|
|
4
|
+
import {DEFAULT_CONFIGS} from './configs';
|
|
5
|
+
import {logger} from './logger';
|
|
6
|
+
import {DataSource} from './typeorm';
|
|
7
|
+
import assert from 'assert';
|
|
8
|
+
import {getWallet, updateWallet} from './entities/wallet.entity';
|
|
9
|
+
import { getV1LocalStorage } from './migration/migration1/v1-data-store';
|
|
10
|
+
import { getAllDocuments } from './entities/document';
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
export const getLocalStorage = getV1LocalStorage;
|
|
14
|
+
|
|
15
|
+
export async function updateNetwork({
|
|
16
|
+
dataStore,
|
|
17
|
+
networkId,
|
|
18
|
+
}: {
|
|
19
|
+
dataStore: DataStore;
|
|
20
|
+
networkId: string;
|
|
21
|
+
}): Promise<void> {
|
|
22
|
+
const network = dataStore.networks.find(item => item.id === networkId);
|
|
23
|
+
|
|
24
|
+
assert(!!network, `Invalid network id ${networkId}`);
|
|
25
|
+
|
|
26
|
+
dataStore.network = network;
|
|
27
|
+
dataStore.networkId = networkId;
|
|
28
|
+
|
|
29
|
+
await updateWallet({dataStore});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function createDataStore(
|
|
33
|
+
_options: DataStoreConfigs,
|
|
34
|
+
): Promise<DataStore> {
|
|
35
|
+
const options: DataStoreConfigs = {
|
|
36
|
+
...DEFAULT_CONFIGS,
|
|
37
|
+
..._options,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
if (!options.defaultNetwork) {
|
|
41
|
+
options.defaultNetwork = options.networks[0].id;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const dataSource: DataSource = await initializeTypeORM(options);
|
|
45
|
+
const dataStore: DataStore = {
|
|
46
|
+
db: dataSource,
|
|
47
|
+
networkId: options.defaultNetwork,
|
|
48
|
+
network: options.networks.find(item => item.id === options.defaultNetwork),
|
|
49
|
+
testNetworkId: options.testNetworkId,
|
|
50
|
+
mainNetworkId: options.mainNetworkId,
|
|
51
|
+
version: null,
|
|
52
|
+
networks: options.networks,
|
|
53
|
+
resolveDocumentNetwork: options.documentNetworkResolver,
|
|
54
|
+
setNetwork: (networkId: string) => {
|
|
55
|
+
logger.debug(`Setting network to ${networkId}`);
|
|
56
|
+
return updateNetwork({dataStore, networkId});
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
logger.debug('Data store initialized');
|
|
61
|
+
|
|
62
|
+
await migrate({dataStore});
|
|
63
|
+
|
|
64
|
+
const wallet = await getWallet({dataStore});
|
|
65
|
+
dataStore.networkId = wallet.networkId;
|
|
66
|
+
dataStore.network = options.networks.find(
|
|
67
|
+
item => item.id === wallet.networkId,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
getAllDocuments({dataStore}).then(documents => {
|
|
71
|
+
logger.debug(`Wallet loaded with ${documents.length} documents`);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return dataStore;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Close the data store connection with the database
|
|
79
|
+
*
|
|
80
|
+
*/
|
|
81
|
+
export async function closeDataStore(dataStore: DataStore) {
|
|
82
|
+
await dataStore.db.destroy();
|
|
83
|
+
}
|
package/src/logger.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const ConsoleTransport = {
|
|
2
|
+
log: (message: string) => {
|
|
3
|
+
console.log(message);
|
|
4
|
+
},
|
|
5
|
+
error: (message: string) => {
|
|
6
|
+
console.error(message);
|
|
7
|
+
},
|
|
8
|
+
debug: (message: string) => {
|
|
9
|
+
console.debug(message);
|
|
10
|
+
},
|
|
11
|
+
warn: (message: string) => {
|
|
12
|
+
console.warn(message);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export let logger = ConsoleTransport;
|
|
17
|
+
|
|
18
|
+
export function setLogger(impl: any) {
|
|
19
|
+
logger = impl;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const createLogger = (prefix: string) => {
|
|
23
|
+
return {
|
|
24
|
+
log: (message: string) => {
|
|
25
|
+
logger.log(`[${prefix}] ${message}`);
|
|
26
|
+
},
|
|
27
|
+
error: (message: string) => {
|
|
28
|
+
logger.error(`[${prefix}] ${message}`);
|
|
29
|
+
},
|
|
30
|
+
debug: (message: string) => {
|
|
31
|
+
logger.debug(`[${prefix}] ${message}`);
|
|
32
|
+
},
|
|
33
|
+
warn: (message: string) => {
|
|
34
|
+
logger.warn(`[${prefix}] ${message}`);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {isRunningOnV1DataStore, migration1} from './migration1';
|
|
2
|
+
import {ContextProps} from '../types';
|
|
3
|
+
import {logger} from '../logger';
|
|
4
|
+
import {createWallet, getWallet, updateWallet} from '../entities/wallet.entity';
|
|
5
|
+
import {bootstrapTables} from './bootstrap-tables';
|
|
6
|
+
|
|
7
|
+
export const CURRENT_DATA_STORE_VERSION = 'v2';
|
|
8
|
+
|
|
9
|
+
export type MigrationResult = {
|
|
10
|
+
migrated: boolean;
|
|
11
|
+
version: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const migrations = [
|
|
15
|
+
migration1,
|
|
16
|
+
// add new migrations here
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
export async function migrate({dataStore}: ContextProps) {
|
|
20
|
+
// bootstrap v2 data
|
|
21
|
+
await bootstrapTables(dataStore.db);
|
|
22
|
+
|
|
23
|
+
// Fetch existing configs from the database
|
|
24
|
+
let existingConfigs = await getWallet({dataStore});
|
|
25
|
+
|
|
26
|
+
// Force v1 migration
|
|
27
|
+
// dataStore.version = 'v1';
|
|
28
|
+
// If no configs exist, create a new one
|
|
29
|
+
if (!existingConfigs) {
|
|
30
|
+
logger.debug('Wallet not found in the database, creating a new wallet...');
|
|
31
|
+
const isV1DataStore = await isRunningOnV1DataStore({dataStore});
|
|
32
|
+
logger.debug(`Is v1 data store: ${isV1DataStore}`);
|
|
33
|
+
dataStore.version = isV1DataStore ? 'v1' : CURRENT_DATA_STORE_VERSION;
|
|
34
|
+
await createWallet({
|
|
35
|
+
dataStore,
|
|
36
|
+
});
|
|
37
|
+
logger.debug('universal wallet created');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (const migrate of migrations) {
|
|
41
|
+
const results = await migrate({dataStore});
|
|
42
|
+
|
|
43
|
+
if (results.migrated) {
|
|
44
|
+
logger.debug('Migration completed');
|
|
45
|
+
dataStore.version = results.version;
|
|
46
|
+
await updateWallet({dataStore});
|
|
47
|
+
} else {
|
|
48
|
+
logger.debug('Migration not required');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
logger.debug(`DataStore version: ${dataStore.version}`);
|
|
53
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import {getV1LocalStorage, getWalletDocuments} from './v1-data-store';
|
|
2
|
+
import {logger} from '../../logger';
|
|
3
|
+
import {migrateV1Data} from './migrate-v1-data';
|
|
4
|
+
import {MigrationResult} from '../index';
|
|
5
|
+
import {ContextProps} from '../../types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Migrate from v1 to v2
|
|
9
|
+
*
|
|
10
|
+
* v1 data store is stored in local storage
|
|
11
|
+
* v2 will store on typeorm
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
export async function migration1({
|
|
15
|
+
dataStore,
|
|
16
|
+
}: ContextProps): Promise<MigrationResult> {
|
|
17
|
+
logger.debug('Checking if v1 migration is required');
|
|
18
|
+
|
|
19
|
+
if (dataStore.version !== 'v1') {
|
|
20
|
+
logger.debug('v1 data migration NOT required');
|
|
21
|
+
return {
|
|
22
|
+
migrated: false,
|
|
23
|
+
version: dataStore.version,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
logger.debug('v1 data Migration required');
|
|
28
|
+
|
|
29
|
+
await migrateV1Data({dataStore});
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
migrated: true,
|
|
33
|
+
version: 'v2',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Check if a migration from v2 is required
|
|
39
|
+
* Once v2 is migrated, the local storage entry will be removed
|
|
40
|
+
*/
|
|
41
|
+
export async function isRunningOnV1DataStore({
|
|
42
|
+
dataStore,
|
|
43
|
+
}: ContextProps): Promise<boolean> {
|
|
44
|
+
// If sdk version is defined, can skip migration
|
|
45
|
+
if (dataStore.version) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const v1LocalStorage = getV1LocalStorage();
|
|
50
|
+
|
|
51
|
+
if (!v1LocalStorage) {
|
|
52
|
+
logger.debug('v1 local storage not found');
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const documents = await getWalletDocuments();
|
|
57
|
+
|
|
58
|
+
if (documents.length === 0) {
|
|
59
|
+
logger.debug('no documents found on v1 data store');
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {getV1LocalStorage} from './v1-data-store';
|
|
2
|
+
import {createDocument} from '../../entities/document';
|
|
3
|
+
import {documentHasType} from '../../helpers';
|
|
4
|
+
|
|
5
|
+
export async function importUniversalWalletDocuments({documents, dataStore}) {
|
|
6
|
+
for (const _document of documents) {
|
|
7
|
+
let document = _document;
|
|
8
|
+
if (documentHasType(document, 'VerifiableCredential') && document.value) {
|
|
9
|
+
document = document.value;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
try {
|
|
13
|
+
await createDocument({
|
|
14
|
+
dataStore,
|
|
15
|
+
json: document,
|
|
16
|
+
});
|
|
17
|
+
} catch (err) {
|
|
18
|
+
console.error(err);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function migrateDocuments({v1Storage, dataStore}) {
|
|
23
|
+
const walletJSON = await v1Storage.getItem('wallet');
|
|
24
|
+
const wallet = JSON.parse(walletJSON);
|
|
25
|
+
|
|
26
|
+
const documents = Object.keys(wallet).map(key => wallet[key]);
|
|
27
|
+
|
|
28
|
+
await importUniversalWalletDocuments({documents, dataStore});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function migrateNotificaions() {}
|
|
32
|
+
|
|
33
|
+
function migrateDevSettings() {}
|
|
34
|
+
|
|
35
|
+
function migrateTransactions() {
|
|
36
|
+
// Will skip this migration for performance improvements
|
|
37
|
+
// That would require Realm db as dependency
|
|
38
|
+
// We can drop the realm.db dependency from the wallet-sdk
|
|
39
|
+
// Transactions will be pulled from subscan into in the new data-store automatically
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export async function migrateV1Data({dataStore}) {
|
|
43
|
+
const v1Storage = getV1LocalStorage();
|
|
44
|
+
|
|
45
|
+
await migrateDocuments({
|
|
46
|
+
v1Storage,
|
|
47
|
+
dataStore,
|
|
48
|
+
});
|
|
49
|
+
await migrateNotificaions();
|
|
50
|
+
await migrateDevSettings();
|
|
51
|
+
await migrateTransactions();
|
|
52
|
+
|
|
53
|
+
// remove localStorage entries
|
|
54
|
+
const walletJSON = await v1Storage.getItem('wallet');
|
|
55
|
+
await v1Storage.setItem('wallet-backup', walletJSON);
|
|
56
|
+
await v1Storage.removeItem('wallet');
|
|
57
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import assert from 'assert';
|
|
2
|
+
|
|
3
|
+
export type LocalStorage = {
|
|
4
|
+
getItem: (key: string) => Promise<string | null>;
|
|
5
|
+
setItem: (key: string, value: string) => Promise<void>;
|
|
6
|
+
removeItem: (key: string) => Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
let _localStorage: LocalStorage;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Legacy data-store was based on AsyncLocalStorage
|
|
13
|
+
* The wallet will inject its implementation here, so that the migration scripts can use it
|
|
14
|
+
*
|
|
15
|
+
* @param _impl
|
|
16
|
+
*/
|
|
17
|
+
export function setV1LocalStorage(_impl: LocalStorage) {
|
|
18
|
+
assert(!!_impl, 'LocalStorage implementation is required');
|
|
19
|
+
|
|
20
|
+
_localStorage = _impl;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getV1LocalStorage(): LocalStorage {
|
|
24
|
+
return _localStorage;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export async function getWalletDocuments() {
|
|
28
|
+
const jsonData = await _localStorage.getItem('wallet');
|
|
29
|
+
|
|
30
|
+
if (!jsonData) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const wallet = JSON.parse(jsonData as string);
|
|
35
|
+
|
|
36
|
+
return Object.keys(wallet).map(key => {
|
|
37
|
+
return wallet[key];
|
|
38
|
+
});
|
|
39
|
+
}
|