diff --git a/asset-transfer-secured-agreement/README.md b/asset-transfer-secured-agreement/README.md index ab9456db..7ebae1d8 100644 --- a/asset-transfer-secured-agreement/README.md +++ b/asset-transfer-secured-agreement/README.md @@ -51,7 +51,7 @@ Like other samples, the Fabric test network is used to deploy and run this sampl npm start # To run the Javascript sample application - cd application-gateway-javascript + cd application-javascript node app.js ``` diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/.eslintrc.json b/asset-transfer-secured-agreement/application-gateway-typescript/.eslintrc.json index cc7230a8..fb2391e0 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/.eslintrc.json +++ b/asset-transfer-secured-agreement/application-gateway-typescript/.eslintrc.json @@ -30,7 +30,10 @@ "sourceType": "module", "ecmaFeatures": { "impliedStrict": true - } + }, + "project": [ + "./tsconfig.json" + ] }, "plugins": [ "@typescript-eslint" @@ -39,7 +42,61 @@ "eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended" - ] + ], + "rules": { + "@typescript-eslint/comma-spacing": [ + "error" + ], + "@typescript-eslint/explicit-function-return-type": [ + "error", + { + "allowExpressions": true + } + ], + "@typescript-eslint/func-call-spacing": [ + "error" + ], + "@typescript-eslint/member-delimiter-style": [ + "error" + ], + "@typescript-eslint/indent": [ + "error", + 4, + { + "SwitchCase": 0 + } + ], + "@typescript-eslint/prefer-nullish-coalescing": [ + "error" + ], + "@typescript-eslint/prefer-optional-chain": [ + "error" + ], + "@typescript-eslint/prefer-reduce-type-parameter": [ + "error" + ], + "@typescript-eslint/prefer-return-this-type": [ + "error" + ], + "@typescript-eslint/quotes": [ + "error", + "single" + ], + "@typescript-eslint/type-annotation-spacing": [ + "error" + ], + "@typescript-eslint/semi": [ + "error" + ], + "@typescript-eslint/space-before-function-paren": [ + "error", + { + "anonymous": "never", + "named": "never", + "asyncArrow": "always" + } + ] + } } ] } \ No newline at end of file diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts index 1b404140..4d311889 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/app.ts @@ -7,7 +7,7 @@ import { connect } from '@hyperledger/fabric-gateway'; import crpto from 'crypto'; import { newGrpcConnection, newIdentity, newSigner, tlsCertPathOrg1, peerEndpointOrg1, peerNameOrg1, certPathOrg1, mspIdOrg1, keyDirectoryPathOrg1, tlsCertPathOrg2, peerEndpointOrg2, peerNameOrg2, certPathOrg2, mspIdOrg2, keyDirectoryPathOrg2 } from './connect'; -import { Asset, AssetPrice, AssetProperties, GREEN, RED, RESET } from './utils'; +import { AssetPrice, AssetProperties, GREEN, RED, RESET } from './utils'; import { ContractWrapper } from './contractWrapper'; const channelName = 'mychannel'; @@ -69,19 +69,19 @@ async function main(): Promise { await readAsset(contractWrapperOrg2, assetKey, mspIdOrg1, mspIdOrg2); // Org1 should be able to read the private data details of the asset. - await readPrivateAsset(contractWrapperOrg1, assetKey, mspIdOrg1) + await readPrivateAsset(contractWrapperOrg1, assetKey, mspIdOrg1); // Org2 is not the owner and does not have the private details, read expected to fail. - await readPrivateAsset(contractWrapperOrg2, assetKey, mspIdOrg2) + await readPrivateAsset(contractWrapperOrg2, assetKey, mspIdOrg2); // Org1 updates the assets public description. - await changePublicDescription(contractWrapperOrg1, assetKey, mspIdOrg1, `Asset ${assetKey} owned by ${mspIdOrg1} is for sale`) + await changePublicDescription(contractWrapperOrg1, assetKey, mspIdOrg1, `Asset ${assetKey} owned by ${mspIdOrg1} is for sale`); // Read the public details by org1. - await readAsset(contractWrapperOrg1, assetKey, mspIdOrg1,mspIdOrg1); + await readAsset(contractWrapperOrg1, assetKey, mspIdOrg1, mspIdOrg1); // Read the public details by org2. - await readAsset(contractWrapperOrg2, assetKey, mspIdOrg1,mspIdOrg2); + await readAsset(contractWrapperOrg2, assetKey, mspIdOrg1, mspIdOrg2); // This is an update to the public state and requires the owner(Org1) to endorse and sent by the owner org client (Org1). // Since the client is from Org2, which is not the owner, this will fail @@ -123,13 +123,13 @@ async function main(): Promise { await agreeToSell(contractWrapperOrg1, assetKey, mspIdOrg1, 100); // Read the public details by org1. - await readAsset(contractWrapperOrg1, assetKey, mspIdOrg1,mspIdOrg1); + await readAsset(contractWrapperOrg1, assetKey, mspIdOrg1, mspIdOrg1); // Read the public details by org2. await readAsset(contractWrapperOrg2, assetKey, mspIdOrg1, mspIdOrg2); // Org1 should be able to read the private data details of the asset. - await readPrivateAsset(contractWrapperOrg1, assetKey, mspIdOrg1,) + await readPrivateAsset(contractWrapperOrg1, assetKey, mspIdOrg1,); // Org1 should be able to read the sale price of this asset await readSalePrice(contractWrapperOrg1, assetKey, mspIdOrg1); @@ -180,46 +180,36 @@ main().catch(error => { process.exitCode = 1; }); -async function createAsset(contract:ContractWrapper, org:string):Promise { +async function createAsset(contract: ContractWrapper, org: string): Promise { console.log(`${GREEN}--> Submit Transaction: CreateAsset, ${assetKey} as ${org} - endorsed by Org1${RESET}`); - await contract.submit('CreateAsset', { - arguments: [assetKey,`Asset ${assetKey} owned by ${org} is not for sale`], - transientData: { asset_properties: AssetProperties.instance('asset_properties', assetKey, 'blue', 35, randomBytes)}, - }); + await contract.createAsset(org, assetKey, { object_type: 'asset_properties', asset_id: assetKey, color: 'blue', size: 35, salt: randomBytes }); console.log(`*** Result: committed, asset ${assetKey} is owned by Org1`); } -async function readAsset(contract:ContractWrapper, assetKey:string, ownerOrg:string, org:string):Promise { +async function readAsset(contract: ContractWrapper, assetKey: string, ownerOrg: string, org: string): Promise { console.log(`${GREEN}--> Evaluate Transactions: ReadAsset as ${org}, - ${assetKey} should be owned by ${ownerOrg}${RESET}`); - - const resultString = await contract.evaluateTransaction('ReadAsset', assetKey); - const result = Asset.parse(resultString); - if (resultString.length !== 0) { - if (result?.ownerOrg === ownerOrg) { + try { + const result = await contract.readAsset(assetKey); + if (result.ownerOrg === ownerOrg) { console.log(`*** Result from ${org} - asset ${result.assetID} owned by ${result.ownerOrg} DESC:${result.publicDescription}`); } else { console.log(`${RED}*** Failed owner check from ${org} - asset ${result.assetID} owned by ${result.ownerOrg} DESC:${result.publicDescription}${RESET}`); } - - }else{ - console.log(`${RED}*** Failed ReadAsset ${RESET}`); + }catch (e) { + console.log(`${RED}*** Failed evaluateTransaction readAsset - ${e}${RESET}`); } - } -async function readPrivateAsset(contract:ContractWrapper, assetKey:string, org:string):Promise { +async function readPrivateAsset(contract: ContractWrapper, assetKey: string, org: string): Promise { try{ console.log(`${GREEN}--> Evaluate Transaction: GetAssetPrivateProperties, - ${assetKey} from organization ${org}${RESET}`); if(org === mspIdOrg2){ - console.log(`${GREEN}* Expected to fail as ${org} is not the owner and does not have the private details${RESET}`) + console.log(`${GREEN}* Expected to fail as ${org} is not the owner and does not have the private details${RESET}`); } - const resultString = await contract.evaluateTransaction('GetAssetPrivateProperties', assetKey); - - const result = Asset.parse(resultString); - + const result = await contract.getAssetPrivateProperties(assetKey); console.log('*** Result:', result); } catch(e){ @@ -227,31 +217,24 @@ async function readPrivateAsset(contract:ContractWrapper, assetKey:string, org:s } } -async function changePublicDescription(contract:ContractWrapper, assetKey:string, org:string, description:string):Promise { +async function changePublicDescription(contract: ContractWrapper, assetKey: string, org: string, description: string): Promise { try { console.log(`${GREEN}--> Submit Transaction: ChangePublicDescription ${assetKey}, as ${org} - endorse by ${org}${RESET}`); - if(org===mspIdOrg2){ - console.log(`${GREEN}* Expected to fail as ${org} is not the owner${RESET}`) + if (org === mspIdOrg2) { + console.log(`${GREEN}* Expected to fail as ${org} is not the owner${RESET}`); } - - await contract.submit('ChangePublicDescription', { - arguments:[assetKey,description], - }); - + await contract.changePublicDescription(assetKey, description); console.log(`*** Result: committed, asset ${assetKey} is now for sale by ${org}`); } catch (e) { console.log(`${RED}*** Failed: ChangePublicDescription - ${e}${RESET}`); } } -async function agreeToSell(contract:ContractWrapper, assetKey:string, org:string, price:number):Promise { +async function agreeToSell(contract: ContractWrapper, assetKey: string, org: string, price: number): Promise { try { console.log(`${GREEN}--> Submit Transaction: AgreeToSell, ${assetKey} as ${org} - endorsed by ${org}${RESET}`); - await contract.submit('AgreeToSell',{ - arguments:[assetKey], - transientData: { asset_price: AssetPrice.instance(assetKey, price, now.toString()) } - }); + await contract.agreeToSell({asset_id:assetKey, price, trade_id:now.toString()}); console.log(`*** Result: committed, ${org} has agreed to sell asset ${assetKey} for ${price}`); } catch (e) { @@ -259,22 +242,14 @@ async function agreeToSell(contract:ContractWrapper, assetKey:string, org:string } } -async function verifyAssetProperties(contract:ContractWrapper, assetKey:string, org:string): Promise { +async function verifyAssetProperties(contract: ContractWrapper, assetKey: string, org: string): Promise { try { console.log(`${GREEN}--> Evalute: VerifyAssetProperties, ${assetKey} as ${org} - endorsed by ${org}${RESET}`); - const resultString = await contract.evaluate('VerifyAssetProperties',{ - arguments:[assetKey], - transientData: { asset_properties: AssetProperties.instance('asset_properties', assetKey, 'blue', 35, randomBytes) }, - }); + const result = await contract.verifyAssetProperties({object_type:'asset_properties', asset_id:assetKey, color:'blue', size:35, salt:randomBytes}, org); - if (resultString.length !== 0) { - const result = Asset.parse(resultString); - if (result) { - console.log(`*** Success VerifyAssetProperties, private information about asset ${assetKey} has been verified by ${org}`); - } else { - console.log(`*** Failed: VerifyAssetProperties, private information about asset ${assetKey} has not been verified by ${org}`); - } + if (result) { + console.log(`*** Success VerifyAssetProperties, private information about asset ${assetKey} has been verified by ${org}`); } else { console.log(`*** Failed: VerifyAssetProperties, private information about asset ${assetKey} has not been verified by ${org}`); } @@ -283,14 +258,11 @@ async function verifyAssetProperties(contract:ContractWrapper, assetKey:string, } } -async function agreeToBuy(contract:ContractWrapper, assetKey:string, org:string, price:number):Promise { +async function agreeToBuy(contract: ContractWrapper, assetKey: string, org: string, price: number): Promise { try { console.log(`${GREEN}--> Submit Transaction: AgreeToBuy, ${assetKey} as ${org} - endorsed by ${org}${RESET}`); - await contract.submit('AgreeToBuy',{ - arguments:[assetKey], - transientData: { asset_price: AssetPrice.instance(assetKey,price,now.toString()) } - }); + await contract.agreeToBuy( {asset_id:assetKey, price, trade_id: now.toString()}); console.log(`*** Result: committed, ${org} has agreed to buy asset ${assetKey} for 100`); } catch (e) { @@ -298,30 +270,29 @@ async function agreeToBuy(contract:ContractWrapper, assetKey:string, org:string, } } -async function readSalePrice(contract:ContractWrapper, assetKey:string, org:string):Promise { +async function readSalePrice(contract: ContractWrapper, assetKey: string, org: string): Promise { try { console.log(`${GREEN}--> Evaluate Transaction: GetAssetSalesPrice, - ${assetKey} from organization ${org}${RESET}`); - if(org===mspIdOrg2){ - console.log(`${GREEN}* Expected to fail as ${org} has not set a sale price${RESET}`) + if(org === mspIdOrg2){ + console.log(`${GREEN}* Expected to fail as ${org} has not set a sale price${RESET}`); } - const resultString = await contract.evaluateTransaction('GetAssetSalesPrice', assetKey); - const result = Asset.parse(resultString); + const result = await contract.getAssetSalesPrice(assetKey); + console.log('*** Result: GetAssetSalesPrice', result); } catch (e) { console.log(`${RED}*** Failed evaluateTransaction GetAssetSalesPrice: ${e}${RESET}`); } } -async function readBidPrice(contract:ContractWrapper, assetKey:string, org:string):Promise { +async function readBidPrice(contract: ContractWrapper, assetKey: string, org: string): Promise { try{ console.log(`${GREEN}--> Evaluate Transaction: GetAssetBidPrice, - ${assetKey} from organization ${org}${RESET}`); - if(org===mspIdOrg1){ - console.log(`${GREEN}* Expected to fail as Org1 has not agreed to buy${RESET}`) + if(org === mspIdOrg1){ + console.log(`${GREEN}* Expected to fail as Org1 has not agreed to buy${RESET}`); } - const resultString = await contract.evaluateTransaction('GetAssetBidPrice', assetKey); - const result = Asset.parse(resultString); + const result = await contract.getAssetBidPrice(assetKey); console.log('*** Result: GetAssetBidPrice', result); } catch (e) { @@ -329,23 +300,24 @@ async function readBidPrice(contract:ContractWrapper, assetKey:string, org:strin } } -async function transferAsset(contract:ContractWrapper, assetKey:string, org:string,buyerOrgID:string, price:number):Promise { +async function transferAsset(contract: ContractWrapper, assetKey: string, org: string, buyerOrgID: string, price: number): Promise { try { - console.log(`${GREEN}--> Submit Transaction: TransferAsset, ${assetKey} as ${org} - endorsed by ${org}${RESET}`); if(org === mspIdOrg2){ - console.log(`${GREEN}* Expected to fail as the owner is Org1${RESET}`) + console.log(`${GREEN}* Expected to fail as the owner is Org1${RESET}`); }else if(price === 110){ - console.log(`${GREEN}* Expected to fail as sell price and the bid price are not the same${RESET}`) + console.log(`${GREEN}* Expected to fail as sell price and the bid price are not the same${RESET}`); } - await contract.submit('TransferAsset', { - arguments:[assetKey,buyerOrgID], - transientData: { - asset_properties: AssetProperties.instance('asset_properties', assetKey, 'blue', 35, randomBytes), - asset_price: AssetPrice.instance(assetKey, price, now.toString()) }, - endorsingOrganizations:[mspIdOrg1,mspIdOrg2] - }); + const assetProperties: AssetProperties = + { object_type:'asset_properties', + asset_id:assetKey, + color:'blue', + size:35, + salt:randomBytes + }; + const assetPrice: AssetPrice = {asset_id: assetKey, price, trade_id:now.toString()}; + await contract.transferAsset(buyerOrgID, assetProperties, assetPrice, [ mspIdOrg1, mspIdOrg2 ]); console.log(`${GREEN}*** Result: committed, ${org} has transfered the asset ${assetKey} to ${mspIdOrg2} ${RESET}`); } catch (e) { @@ -353,14 +325,14 @@ async function transferAsset(contract:ContractWrapper, assetKey:string, org:stri } } -async function readPrivateAssetAfterTransfer(contract:ContractWrapper, assetKey:string, org:string):Promise { +async function readPrivateAssetAfterTransfer(contract: ContractWrapper, assetKey: string, org: string): Promise { try{ console.log(`${GREEN}--> Evaluate Transaction: GetAssetPrivateProperties, - ${assetKey} from organization ${org}${RESET}`); - if(org === mspIdOrg1){ - console.log(`${GREEN}* Expected to fail as ${org} is not the owner and does not have the private details${RESET}`) + if(org === mspIdOrg1) { + console.log(`${GREEN}* Expected to fail as ${org} is not the owner and does not have the private details${RESET}`); } - const resultString = await contract.evaluateTransaction('GetAssetPrivateProperties', assetKey); - const result = Asset.parse(resultString); + + const result = await contract.getAssetPrivateProperties(assetKey); console.log('*** Result:', result); } @@ -369,16 +341,14 @@ async function readPrivateAssetAfterTransfer(contract:ContractWrapper, assetKey: } } -async function changePublicDescriptionAfterTransfer(contract:ContractWrapper, assetKey:string, org:string, description:string):Promise { +async function changePublicDescriptionAfterTransfer(contract: ContractWrapper, assetKey: string, org: string, description: string): Promise { try { console.log(`${GREEN}--> Submit Transaction: changePublicDescription ${assetKey}, as ${org} - endorse by ${org}${RESET}`); - if(org===mspIdOrg1){ - console.log(`${GREEN}* Expected to fail as ${org} is not the owner${RESET}`) + if(org === mspIdOrg1) { + console.log(`${GREEN}* Expected to fail as ${org} is not the owner${RESET}`); } - await contract.submit('ChangePublicDescription', { - arguments:[assetKey,description], - }); + await contract.changePublicDescription(assetKey, description); console.log(`*** Result: committed, asset ${assetKey} is now for sale by ${org}`); } catch (e) { diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts index dd7159e3..e10f8bd6 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/connect.ts @@ -15,7 +15,7 @@ export const mspIdOrg1 = 'Org1MSP'; export const mspIdOrg2 = 'Org2MSP'; // Path to org1 crypto materials. -export const cryptoPathOrg1 = path.resolve(__dirname, '..', '..', '..', '../../sample-2.4.3/fabric-samples/test-network', 'organizations', 'peerOrganizations', 'org1.example.com'); +export const cryptoPathOrg1 = path.resolve(__dirname, '..', '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com'); // Path to user private key directory. export const keyDirectoryPathOrg1 = path.resolve(cryptoPathOrg1, 'users', 'User1@org1.example.com', 'msp', 'keystore'); @@ -32,7 +32,7 @@ export const cryptoPathOrg2 = path.resolve( '..', '..', '..', - '../../sample-2.4.3/fabric-samples/test-network', + 'test-network', 'organizations', 'peerOrganizations', 'org2.example.com' diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts index fc62948b..2a180fd9 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/contractWrapper.ts @@ -3,31 +3,94 @@ * * SPDX-License-Identifier: Apache-2.0 */ -import { Contract, ProposalOptions } from '@hyperledger/fabric-gateway'; +import { Contract } from '@hyperledger/fabric-gateway'; import { TextDecoder } from 'util'; +import { Asset, AssetPrice, AssetProperties, parse } from './utils'; export class ContractWrapper { contract?: Contract; - utf8Decoder: TextDecoder = new TextDecoder(); + utf8Decoder: TextDecoder =new TextDecoder(); - public constructor(contract:Contract) { + public constructor(contract: Contract) { this.contract = contract; } - public async submit(transactionName:string, options: ProposalOptions ) { - await this.contract?.submit(transactionName, options); - return; + public async createAsset(org: string, assetKey: string, assetProperties: AssetProperties): Promise { + await this.contract?.submit('CreateAsset', { + arguments: [assetKey, `Asset ${assetKey} owned by ${org} is not for sale`], + transientData: { asset_properties: JSON.stringify(assetProperties)}, + }); } - public async evaluate(transactionName:string, options: ProposalOptions): Promise { - const resultBytes = await this.contract?.evaluate(transactionName, options); + public async readAsset( assetKey: string): Promise { + const resultBytes = await this.contract?.evaluateTransaction('ReadAsset', assetKey); const result = this.utf8Decoder.decode(resultBytes); - return result; + if (result.length !== 0) { + return parse(result); + } else { + throw new Error('No Asset Found'); + } } - public async evaluateTransaction(transactionName:string, ...args: (string | Uint8Array)[]): Promise { - const resultBytes = await this.contract?.evaluateTransaction(transactionName, ...args); - return this.utf8Decoder.decode(resultBytes); + public async getAssetPrivateProperties( assetKey: string ): Promise { + const resultBytes = await this.contract?.evaluateTransaction('GetAssetPrivateProperties', assetKey); + const result = this.utf8Decoder.decode(resultBytes); + return parse(result); + } + + public async changePublicDescription(assetKey: string, description: string): Promise { + await this.contract?.submit('ChangePublicDescription', { + arguments:[assetKey, description], + }); + } + + public async agreeToSell(asset_price: AssetPrice): Promise { + await this.contract?.submit('AgreeToSell', { + arguments:[asset_price.asset_id], + transientData: {asset_price: JSON.stringify(asset_price)} + }); + } + + public async verifyAssetProperties(assetProperties: AssetProperties, org: string): Promise { + const resultBytes = await this.contract?.evaluate('VerifyAssetProperties', { + arguments:[assetProperties.asset_id], + transientData: {asset_properties: JSON.stringify(assetProperties)}, + }); + const result = this.utf8Decoder.decode(resultBytes); + if (result.length !== 0) { + return parse(result); + } else { + throw new Error(`Private information about asset ${assetProperties.asset_id} has not been verified by ${org}`); + } + } + + public async agreeToBuy(asset_price: AssetPrice): Promise { + await this.contract?.submit('AgreeToBuy', { + arguments:[asset_price.asset_id], + transientData: {asset_price: JSON.stringify(asset_price)} + }); + } + + public async getAssetSalesPrice(assetKey: string): Promise { + const resultBytes = await this.contract?.evaluateTransaction('GetAssetSalesPrice', assetKey); + const result = this.utf8Decoder.decode(resultBytes); + return parse(result); + } + + public async getAssetBidPrice( assetKey: string): Promise { + const resultBytes = await this.contract?.evaluateTransaction('GetAssetBidPrice', assetKey); + const result = this.utf8Decoder.decode(resultBytes); + return parse(result); + } + + public async transferAsset(buyerOrgID: string, asset_properties: AssetProperties, asset_price: AssetPrice, endorsingOrganizations: string[]): Promise { + await this.contract?.submit('TransferAsset', { + arguments:[asset_properties.asset_id, buyerOrgID], + transientData: { + asset_properties: JSON.stringify(asset_properties), + asset_price: JSON.stringify(asset_price)}, + endorsingOrganizations:endorsingOrganizations + }); } } \ No newline at end of file diff --git a/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts b/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts index b7de50ff..fa496142 100644 --- a/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts +++ b/asset-transfer-secured-agreement/application-gateway-typescript/src/utils.ts @@ -8,105 +8,27 @@ export const RED = '\x1b[31m\n'; export const GREEN = '\x1b[32m\n'; export const RESET = '\x1b[0m'; -export interface asset { - objectType: string, - assetID: string, - ownerOrg: string, - publicDescription: string, +export interface Asset { + objectType: string; + assetID: string; + ownerOrg: string; + publicDescription: string; } -export interface asset_properties { - object_type: string, - asset_id: string, - color: string, - size: number, - salt: string +export interface AssetProperties { + object_type: string; + asset_id: string; + color: string; + size: number; + salt: string; } -export interface asset_price { - asset_id: string, - price: number, - trade_id: string +export interface AssetPrice { + asset_id: string; + price: number; + trade_id: string; } -export interface asset_price { - asset_id: string, - price: number, - trade_id: string -} - -export class AssetProperties { - - asset_properties: asset_properties; - - private constructor (asset_properties: asset_properties) { - this.asset_properties = asset_properties; - } - - static instance(object_type: string, asset_id: string, color: string, size: number, salt: string): string { - const asset_properties : asset_properties = { - object_type, - asset_id, - color, - size, - salt, - }; - return new AssetProperties(asset_properties).serialize(); - } - - private serialize(): string { - return JSON.stringify(this.asset_properties); - } - -} - -export class Asset { - - asset: asset; - - private constructor (asset: asset) { - this.asset = asset; - } - - static instance( objectType: string, assetID: string, ownerOrg: string, publicDescription: string): string { - const asset = { - objectType, - assetID, - ownerOrg, - publicDescription - } - return new Asset(asset).serialize(); - } - - private serialize(): string { - return JSON.stringify(this.asset); - } - - static parse(asset: string): asset { - return JSON.parse(asset); - } - -} - -export class AssetPrice { - - asset_price: asset_price; - - constructor (asset_price : asset_price) { - this.asset_price = asset_price; - } - - static instance(asset_id: string, price:number, trade_id: string): string { - const asset_price = { - asset_id, - price, - trade_id - } - return new AssetPrice(asset_price).serialize() - } - - private serialize(): string { - return JSON.stringify(this.asset_price); - } - +export function parse(data: string): T { + return JSON.parse(data); } \ No newline at end of file