diff --git a/src/constants.ts b/src/constants.ts index 9b96674..316cdf6 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -12,14 +12,13 @@ export const Path = { deposit: () => `${Path.app(appName).root()}/deposit`, depositOfUser: (userAddress: string) => `${Path.app(appName).deposit()}/${userAddress}`, billingConfig: () => `${Path.app(appName).root()}/billingConfig`, - billingConfigOfService: (serviceName: string) => `${Path.app(appName).billingConfig()}/service/${serviceName}`, - service: (serviceName: string) => `${Path.app(appName).root()}/service/${serviceName}`, - userOfService: (serviceName: string, userAddress: string) => - `${Path.app(appName).service(serviceName)}/${userAddress}`, - request: (serviceName: string, userAddress: string, requestKey: string) => - `${Path.app(appName).userOfService(serviceName, userAddress)}/${requestKey}/request`, - response: (serviceName: string, userAddress: string, requestKey: string) => - `${Path.app(appName).userOfService(serviceName, userAddress)}/${requestKey}/response`, + service: () => `${Path.app(appName).root()}/service/`, + userOfService: (userAddress: string) => + `${Path.app(appName).service()}/${userAddress}`, + request: (userAddress: string, requestKey: string) => + `${Path.app(appName).userOfService(userAddress)}/${requestKey}/request`, + response: (userAddress: string, requestKey: string) => + `${Path.app(appName).userOfService(userAddress)}/${requestKey}/response`, } }, transfer: (from: string, to: string, transferKey: string) => diff --git a/src/handlers/handler.ts b/src/handlers/handler.ts index 1b068a9..725f1e6 100644 --- a/src/handlers/handler.ts +++ b/src/handlers/handler.ts @@ -30,18 +30,17 @@ export default class Handler { * You should connect before subscibe. * @param {string} userAddress - Address of account you request with. * @param {string} appName - App name you want to subscribe. - * @param {string} serviceName - Service name you want to subscribe. * @param {Function(valueChangedEvent: any)} callback - A callback function to handle response. It will be called when response is written. * @returns SubscribeId. */ - async subscribe(userAddress:string, appName: string, serviceName: string, callback: (valueChangedEvent: any) => any) { - if (this.checkSubscribeTableExists(userAddress, appName, serviceName)){ + async subscribe(userAddress:string, appName: string, callback: (valueChangedEvent: any) => any) { + if (this.checkSubscribeTableExists(userAddress, appName)){ throw new Error("Already subscribed"); } const subscribeId = await this.ain.em.subscribe( "VALUE_CHANGED", { - path: Path.app(appName).response(serviceName, userAddress, "$requestKey"), + path: Path.app(appName).response(userAddress, "$requestKey"), event_source: "USER", }, (valueChangedEvent) => { @@ -51,16 +50,16 @@ export default class Handler { throw new Error(err.message); }, ); - this.addToSubscribeTable(userAddress, appName, serviceName, subscribeId); + this.addToSubscribeTable(userAddress, appName, subscribeId); return subscribeId; } - private checkSubscribeTableExists(userAddress:string, appName:string, serviceName: string) { - return _.has(this.subscribeTable, [userAddress, appName, serviceName]); + private checkSubscribeTableExists(userAddress:string, appName:string,) { + return _.has(this.subscribeTable, [userAddress, appName]); } - private addToSubscribeTable(userAddress:string, appName: string, serviceName: string, filterId: string) { - _.set(this.subscribeTable, [userAddress, appName], {serviceName:filterId}); + private addToSubscribeTable(userAddress:string, appName: string, filterId: string) { + _.set(this.subscribeTable, [userAddress], {appName:filterId}); } /** @@ -76,20 +75,19 @@ export default class Handler { * Unsubscribe to specific service reponse. * @param {string} userAddress - Address of account you want to unsubscribe. * @param {string} appName - App name you want to unsubscribe. - * @param {string} serviceName - Service name you want to unsubscribe. * @returns True if successfuly unsubscribed. */ - unsubscribe(userAddress:string, appName: string, serviceName: string) { - if (!this.checkSubscribeTableExists(userAddress, appName, serviceName)) { + unsubscribe(userAddress:string, appName: string) { + if (!this.checkSubscribeTableExists(userAddress, appName)) { throw new Error("Not subscribed"); } this.ain.em.unsubscribe( - this.subscribeTable[userAddress][appName][serviceName], + this.subscribeTable[userAddress][appName], (err)=>{ if (err) { throw new Error(err.message); } else { - this.subscribeTable[userAddress][appName][serviceName] = null; + this.subscribeTable[userAddress][appName] = null; return true; } }); diff --git a/src/modules/admin.ts b/src/modules/admin.ts index 6207d47..b52d65e 100644 --- a/src/modules/admin.ts +++ b/src/modules/admin.ts @@ -57,7 +57,6 @@ export default class Admin extends ModuleBase { } const requestData: request = { appName: req.body.valuePath[1], - serviceName: req.body.valuePath[3], requesterAddress: req.body.auth.addr, requestKey: req.body.valuePath[5], requestData: req.body.value.prompt, diff --git a/src/modules/app.ts b/src/modules/app.ts index e3384e3..71354de 100644 --- a/src/modules/app.ts +++ b/src/modules/app.ts @@ -1,6 +1,6 @@ import { SetOperation } from "@ainblockchain/ain-js/lib/types"; import { Path } from "../constants"; -import { appBillingConfig, serviceBillingConfig, setRuleParam, setTriggerFunctionParm, triggerFunctionConfig } from "../types/type"; +import { appBillingConfig, setRuleParam, setTriggerFunctionParm, triggerFunctionConfig } from "../types/type"; import { buildSetOperation } from "../utils/builder"; import ModuleBase from "./moduleBase"; @@ -33,12 +33,8 @@ export default class App extends ModuleBase { const depositAddress = this.getDefaultAccount().address; const defaultConfig: appBillingConfig = { depositAddress, - service: { - default: { - costPerToken: 0, - minCost: 0, - } - } + costPerToken: 0, + minCost: 0, } const configOp = this.buildSetAppBillingConfigOp(appName, defaultConfig); setBillingConfigOps.push(configOp); @@ -64,19 +60,6 @@ export default class App extends ModuleBase { return await this.sendTransaction(txBody); } - /** - * Set billing config to a specific service. - * @param {string} appName - * @param {string} serviceName - * @param {serviceBillingConfig} config - * @returns Result of transaction. - */ - async setServiceBillingConfig(appName: string, serviceName: string, config: serviceBillingConfig) { - const setConfigOp = this.buildSetServiceBillingConfigOp(appName, serviceName, config); - const txBody = this.buildTxBody(setConfigOp); - return await this.sendTransaction(txBody); - } - /** * Get billing config of app * @param {string} appName @@ -154,32 +137,19 @@ export default class App extends ModuleBase { * Check cost of request and check if account can pay. You should use this function before send or handle request. * If you don't set address, it will use default account's address. * @param {string} appName - App name you want to request service to. - * @param {string} serviceName - Service name you want to request to. * @param {string} prompt - Data you want to request to service . * @param {string=} userAddress - Address of account you want to check balance. You should set default account if you don't provide address. * @returns Result cost of service. It throws error when user can't pay. */ - async checkCostAndBalance(appName: string, serviceName: string, value: string, requesterAddress?: string) { + async checkCostAndBalance(appName: string, value: string, requesterAddress?: string) { requesterAddress = requesterAddress ? requesterAddress : this.getDefaultAccount().address; - const billingConfig = (await this.getBillingConfig(appName)).service; - const serviceBillingConfig = billingConfig.default; - if(billingConfig[serviceName]) { - if(billingConfig[serviceName].costPerToken) { - serviceBillingConfig.costPerToken = billingConfig[serviceName].costPerToken; - } - if(billingConfig[serviceName].minCost) { - serviceBillingConfig.minCost = billingConfig[serviceName].minCost; - } - if(billingConfig[serviceName].maxCost) { - serviceBillingConfig.maxCost = billingConfig[serviceName].maxCost; - } - } + const billingConfig = (await this.getBillingConfig(appName)); const token = value.split(' ').length; - let cost = token * serviceBillingConfig.costPerToken; - if (serviceBillingConfig.minCost && cost < serviceBillingConfig.minCost) { - cost = serviceBillingConfig.minCost; - } else if (serviceBillingConfig.maxCost && cost > serviceBillingConfig.maxCost) { - cost = serviceBillingConfig.maxCost; + let cost = token * billingConfig.costPerToken; + if (billingConfig.minCost && cost < billingConfig.minCost) { + cost = billingConfig.minCost; + } else if (billingConfig.maxCost && cost > billingConfig.maxCost) { + cost = billingConfig.maxCost; } const balance = await this.getCreditBalance(appName, requesterAddress); if (balance < cost) { @@ -197,12 +167,6 @@ export default class App extends ModuleBase { const path = Path.app(appName).billingConfig(); return buildSetOperation("SET_VALUE", path, config); } - - private buildSetServiceBillingConfigOp(appName: string, serviceName: string, config: serviceBillingConfig) { - const path = Path.app(appName).billingConfigOfService(serviceName); - return buildSetOperation("SET_VALUE", path, config); - } - private buildCreateAppOp(appName: string): SetOperation { const path = `/manage_app/${appName}/create/${Date.now()}`; const adminAccount = this.getDefaultAccount(); @@ -268,18 +232,18 @@ export default class App extends ModuleBase { } }, request: { - ref: Path.app(appName).request("$serviceName", "$userAddress", "$requestKey"), + ref: Path.app(appName).request("$userAddress", "$requestKey"), value: { ".rule": { write: "auth.addr === $userAddress && getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) !== null && " + - "(!util.isEmpty(getValue(`/apps/" + `${appName}` + "/billingConfig/` + $serviceName + `/minCost`))) && (getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/` + $serviceName + `/minCost`)) || " + + "(!util.isEmpty(getValue(`/apps/" + `${appName}` + "/billingConfig/minCost`))) && (getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/minCost`)) || " + "getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/service/default/minCost`)" } } }, response: { - ref: Path.app(appName).response("$serviceName", "userAddress", "$requestKey"), + ref: Path.app(appName).response("userAddress", "$requestKey"), value: { ".rule": { write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && util.isString(newData.status)" diff --git a/src/modules/service.ts b/src/modules/service.ts index 2128738..f00facc 100644 --- a/src/modules/service.ts +++ b/src/modules/service.ts @@ -30,13 +30,12 @@ export default class Service extends ModuleBase { /** * Request service to app. You can use handler to get response. If you don't set address, it will use default account's address. * @param {string} appName - App name you want to request service to. - * @param {string} serviceName - Service name you want to request. * @param {string} prompt - Data you want to request to service . * @param {string=} userAddress - Address of account you want to use for request. You should set default account if you don't provide address. * @returns RequestKey. You can use it to get response by handler. */ - async writeRequest(appName: string, serviceName: string, prompt: string, userAddress?: string) { - await this.app.checkCostAndBalance(appName, serviceName, prompt, userAddress); - return await this.useService.writeRequest(appName, serviceName, prompt, userAddress); + async writeRequest(appName: string, prompt: string, userAddress?: string) { + await this.app.checkCostAndBalance(appName, prompt, userAddress); + return await this.useService.writeRequest(appName, prompt, userAddress); } } diff --git a/src/modules/service/useService.ts b/src/modules/service/useService.ts index 1aa364a..ffcc81f 100644 --- a/src/modules/service/useService.ts +++ b/src/modules/service/useService.ts @@ -5,10 +5,10 @@ import { buildSetOperation } from "../../utils/builder"; import ServiceBase from "./serviceBase"; export default class UseService extends ServiceBase{ - async writeRequest(appName: string, serviceName: string, value: string, requesterAddress?: string) { + async writeRequest(appName: string, value: string, requesterAddress?: string) { const requestKey = Date.now(); requesterAddress = requesterAddress ? requesterAddress : this.wallet.getDefaultAddress(); - const requestPath = Path.app(appName).request(serviceName, requesterAddress, requestKey); + const requestPath = Path.app(appName).request(requesterAddress, requestKey); const requestData = { prompt: value, } @@ -19,8 +19,8 @@ export default class UseService extends ServiceBase{ } async writeResponse(response: response) { - const { responseData, status, requesterAddress, requestKey, appName, serviceName, cost } = response; - const responsePath = Path.app(appName).response(serviceName, requesterAddress, requestKey); + const { responseData, status, requesterAddress, requestKey, appName, cost } = response; + const responsePath = Path.app(appName).response(requesterAddress, requestKey); const responseValue = { status, data: responseData, diff --git a/src/types/type.ts b/src/types/type.ts index 5830713..52d3812 100644 --- a/src/types/type.ts +++ b/src/types/type.ts @@ -16,18 +16,13 @@ export type setRuleParam = { ref: string; } & writeRuleConfig; -export type serviceBillingConfig = { + +export type appBillingConfig = { + depositAddress: string; costPerToken: number; minCost: number; maxCost?: number; responseTimeout?: number; -} - -export type appBillingConfig = { - depositAddress: string; - service: { - [serviceName: string]: serviceBillingConfig; - } }; export enum HISTORY_TYPE { @@ -59,7 +54,6 @@ export type request = { requestData: string, requesterAddress: string, requestKey: string, - serviceName: string, appName: string, };