diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 27c6f199..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "workbench.colorCustomizations": { - "activityBar.activeBackground": "#67b7ac", - "activityBar.background": "#67b7ac", - "activityBar.foreground": "#15202b", - "activityBar.inactiveForeground": "#15202b99", - "activityBarBadge.background": "#a152ad", - "activityBarBadge.foreground": "#e7e7e7", - "commandCenter.border": "#15202b99", - "sash.hoverBorder": "#67b7ac", - "statusBar.background": "#4c9f94", - "statusBar.foreground": "#15202b", - "statusBarItem.hoverBackground": "#3c7c74", - "statusBarItem.remoteBackground": "#4c9f94", - "statusBarItem.remoteForeground": "#15202b", - "titleBar.activeBackground": "#4c9f94", - "titleBar.activeForeground": "#15202b", - "titleBar.inactiveBackground": "#4c9f9499", - "titleBar.inactiveForeground": "#15202b99" - }, - "peacock.color": "#4c9f94" -} \ No newline at end of file diff --git a/src/controller/asset_controller.ts b/src/controller/asset_controller.ts new file mode 100644 index 00000000..f4239025 --- /dev/null +++ b/src/controller/asset_controller.ts @@ -0,0 +1,254 @@ +import express from 'express'; +import * as Cord from '@cord.network/sdk'; +import * as Vc from '@cord.network/vc-export'; +import { + AssetCreateRequest, + AssetCreate, + AssetIssueRequest, + AssetIssue, + AssetTransferRequest, + AssetTransfer, +} from '../entity/Asset'; +import { getConnection } from 'typeorm'; + +const contextFields = [ + 'domain', + 'action', + 'version', + 'entity_one_id', + 'entity_one_uri', + 'entity_two_id', + 'entity_two_uri', + 'transaction_id', + 'message_id', + 'timestamp', + 'ttl', + 'location', +]; + +const validateFields = ( + data: any, + requiredFields: string[], + res: express.Response +) => { + for (const field of requiredFields) { + if (!data.hasOwnProperty(field)) { + res.status(400).json({ error: `Bad Request - ${field} is not provided` }); + return false; + } + } + return true; +}; + +export async function createAsset(req: express.Request, res: express.Response) { + const data = req.body; + + const messageFields = [ + 'asset_quantity', + 'credential_hash', + 'issuer_did', + 'network_author_identity', + 'authorization', + 'asset_uri', + 'sign_call_back', + ]; + + if (!validateFields(data, ['context', 'message'], res)) return; + if (!validateFields(data.context, contextFields, res)) return; + if (!validateFields(data.message, messageFields, res)) return; + + try { + const assetCreateRequest = new AssetCreateRequest(); + assetCreateRequest.data = data; + await getConnection().manager.save(assetCreateRequest); + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + + let asssetVC; + try { + asssetVC = { + verifiableCredential: { + '@context': ['string'], + id: 'string', + type: ['string'], + issuer: 'string', + issuanceDate: '2024-06-18T04:39:21.583Z', + expirationDate: '2024-06-18T04:39:21.583Z', + credentialSubject: { + id: 'string', + bearerToken: { + type: 'string', + symbol: 'string', + amount: 0, + }, + }, + proof: { + type: 'string', + created: '2024-06-18T04:39:21.583Z', + proofPurpose: 'string', + verificationMethod: 'string', + jws: 'string', + }, + }, + }; + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + + try { + const assetCreate = new AssetCreate(); + assetCreate.data = asssetVC as any; + await getConnection().manager.save(assetCreate); + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + res.status(201).json(asssetVC); +} + +export async function issueAsset(req: express.Request, res: express.Response) { + const data = req.body; + + const messageFields = [ + 'asset_id', + 'asset_owner', + 'asset_issuance_qty', + 'issuer', + 'space', + 'digest', + 'asset_uri', + 'network_author_identity', + 'authorization', + 'sign_call_back', + ]; + + if (!validateFields(data, ['context', 'message'], res)) return; + if (!validateFields(data.context, contextFields, res)) return; + if (!validateFields(data.message, messageFields, res)) return; + + try { + const assetIssueRequest = new AssetIssueRequest(); + assetIssueRequest.data = data; + await getConnection().manager.save(assetIssueRequest); + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + + let assetVcIssue; + try { + assetVcIssue = { + verifiableCredential: { + '@context': ['string'], + id: 'string', + type: ['string'], + issuer: 'string', + issuanceDate: '2024-06-18T04:39:21.583Z', + expirationDate: '2024-06-18T04:39:21.583Z', + credentialSubject: { + id: 'string', + bearerToken: { + type: 'string', + symbol: 'string', + amount: 0, + }, + }, + proof: { + type: 'string', + created: '2024-06-18T04:39:21.583Z', + proofPurpose: 'string', + verificationMethod: 'string', + jws: 'string', + }, + }, + }; + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + + try { + const assetIssue = new AssetIssue(); + assetIssue.data = assetVcIssue as any; + await getConnection().manager.save(assetIssue); + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + res.status(201).json(assetVcIssue); +} + +export async function transferAsset( + req: express.Request, + res: express.Response +) { + const data = req.body; + + const messageFields = [ + 'asset_id', + 'asset_instance_id', + 'asset_owner', + 'new_asset_owner', + 'digest', + 'network_author_identity', + 'sign_call_back', + ]; + + if (!validateFields(data, ['context', 'message'], res)) return; + if (!validateFields(data.context, contextFields, res)) return; + if (!validateFields(data.message, messageFields, res)) return; + + try { + const assetTransferRequest = new AssetTransferRequest(); + assetTransferRequest.data = data; + await getConnection().manager.save(assetTransferRequest); + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + + let asssetVCtransfer; + try { + asssetVCtransfer = { + verifiableCredential: { + '@context': ['string'], + id: 'string', + type: ['string'], + issuer: 'string', + issuanceDate: '2024-06-18T04:39:21.583Z', + expirationDate: '2024-06-18T04:39:21.583Z', + credentialSubject: { + id: 'string', + bearerToken: { + type: 'string', + symbol: 'string', + amount: 0, + }, + }, + proof: { + type: 'string', + created: '2024-06-18T04:39:21.583Z', + proofPurpose: 'string', + verificationMethod: 'string', + jws: 'string', + }, + }, + }; + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + + try { + const assetTransfer = new AssetTransfer(); + assetTransfer.data = asssetVCtransfer as any; + await getConnection().manager.save(assetTransfer); + } catch (error) { + console.log(error); + return res.status(500).json(error); + } + res.status(201).json(asssetVCtransfer); +} diff --git a/src/entity/Asset.ts b/src/entity/Asset.ts new file mode 100644 index 00000000..584fce68 --- /dev/null +++ b/src/entity/Asset.ts @@ -0,0 +1,68 @@ +import { Entity, PrimaryColumn, Column, BeforeInsert, Unique } from "typeorm"; +import "reflect-metadata"; + +@Entity() +export class AssetCreateRequest { + + @PrimaryColumn() + id?: string; + + @Column('json') + data?: string; + +} + +@Entity() +export class AssetCreate { + + @PrimaryColumn() + id?: string; + + @Column('json') + data?: string; + +} + +@Entity() +export class AssetIssueRequest { + + @PrimaryColumn() + id?: string; + + @Column('json') + data?: string; + +} + +@Entity() +export class AssetIssue { + + @PrimaryColumn() + id?: string; + + @Column('json') + data?: string; + +} + +@Entity() +export class AssetTransferRequest { + + @PrimaryColumn() + id?: string; + + @Column('json') + data?: string; + +} + +@Entity() +export class AssetTransfer { + + @PrimaryColumn() + id?: string; + + @Column('json') + data?: string; + +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index ef7877c7..4c893eba 100644 --- a/src/index.ts +++ b/src/index.ts @@ -14,6 +14,7 @@ import { revokeCred, updateCred, } from './controller/credential_controller'; +import {createAsset, issueAsset, transferAsset} from './controller/asset_controller' const app = express(); export const { PORT } = process.env; @@ -23,6 +24,7 @@ app.use(express.json()); const credentialRouter = express.Router({ mergeParams: true }); const schemaRouter = express.Router({ mergeParams: true }); +const assetRouter = express.Router({ mergeParams: true }); credentialRouter.post('/', async (req, res) => { return await issueVC(req, res); @@ -48,6 +50,18 @@ schemaRouter.get('/:id', async (req, res) => { return await getSchemaById(req, res); }); +assetRouter.post('/create', async (req, res) => { + return await createAsset(req, res) +}) + +assetRouter.post('/issue', async (req, res) => { + return await issueAsset(req, res) +}) + +assetRouter.post('/transfer', async (req, res) => { + return await transferAsset(req, res) +}) + const openApiDocumentation = JSON.parse( fs.readFileSync('./apis.json').toString() ); @@ -55,6 +69,7 @@ const openApiDocumentation = JSON.parse( app.use('/docs', swaggerUi.serve, swaggerUi.setup(openApiDocumentation)); app.use('/api/v1/schema', schemaRouter); app.use('/api/v1/cred', credentialRouter); +app.use('/api/v1/asset',assetRouter) app.post('/api/v1/docHash', async (req, res) => { return await documentHashOnChain(req, res);