diff --git a/src/modules/app.ts b/src/modules/app.ts index 23932b1..04233f9 100644 --- a/src/modules/app.ts +++ b/src/modules/app.ts @@ -1,111 +1,9 @@ import { SetOperation } from "@ainblockchain/ain-js/lib/types"; import { Path } from "../constants"; -import { appBillingConfig, setDefaultFlag, setRuleParam, setTriggerFunctionParm, triggerFunctionConfig } from "../types/type"; +import { appBillingConfig, setRuleParam, setTriggerFunctionParm, triggerFunctionConfig } from "../types/type"; import { buildSetOperation } from "../utils/builder"; import ModuleBase from "./moduleBase"; -// FIXME(yoojin): move to constant. -const defaultAppRules = (appName: string): { [type: string]: { ref: string, value: object } } => { - const rootRef = Path.app(appName).root(); - return { - root: { - ref: rootRef, - value: { - ".rule": { - write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true" - } - } - }, - deposit: { - ref: `${Path.app(appName).depositOfUser("$userAddress")}/$transferKey`, - value: { - ".rule": { - write: "data === null && util.isNumber(newData) && getValue(`/transfer/` + $userAddress + `/` + getValue(`/apps/" + `${appName}` + "/billingConfig/depositAddress`) + `/` + $transferKey + `/value`) === newData" - } - } - }, - balance: { - ref: Path.app(appName).balanceOfUser("$userAddress"), - value: { - ".rule": { - write: "(util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true) && util.isNumber(newData)" - } - } - }, - balanceHistory: { - ref: `${rootRef}/balance/$userAddress/history/$timestamp_and_type`, - value: { - ".rule": { - write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && util.isNumber(newData.amount) && (newData.type === 'DEPOSIT' || newData.type === 'USAGE')" - } - } - }, - request: { - ref: Path.app(appName).request("$serviceName", "$userAddress", "$requestKey"), - value: { - ".rule": { - write: - "auth.addr === $userAddress && getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) !== null && " + - "((getValue(`/apps/" + `${appName}` + "/billingConfig/` + $serviceName) !== null) && (getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/` + $serviceName + `/minCost`)) || " + - "getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/service/default/minCost`)" - } - } - }, - response: { - ref: Path.app(appName).response("$serviceName", "userAddress", "$requestKey"), - value: { - ".rule": { - write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && util.isString(newData.status)" - } - }, - }, - billingConfig: { - ref: Path.app(appName).billingConfig(), - value: { - ".rule": { - write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && " + - "util.isString(newData.depositAddress) && util.isDict(newData.service) && util.isDict(newData.service.default)", - } - } - }, - billingConfigOfService: { - ref: Path.app(appName).billingConfigOfService("$serviceName"), - value: { - ".rule": { - write: "util.isAppAdmin(`" + `${appName}` + "`, auth,addr, getValue) === true && util.isDict(newData) && util.isNumber(newData.minCost)", - } - } - } - } -} - -const defaultAppFunctions = (appName: string) => { - return { - deposit: (url: string) => { - return { - ref: `${Path.app(appName).depositOfUser("$userAddress")}/$transferKey`, - function_type: "REST", - function_id: "deposit-trigger", - function_url: url, - } - }, - service: (url: string) => { - return { - ref: Path.app(appName).request("$serviceName", "$userAddress", "$requestKey"), - function_type: "REST", - function_id: "service-trigger", - function_url: url, - } - } - } -} - -// FIXME(yoojin): move to types. -// NOTE(yoojin): temporary type. service url may be changed to array? -interface TriggerFunctionUrlMap { - [type: string]: string -} - export default class App extends ModuleBase { /** * Create App for your AI Service on AI Network. @@ -115,31 +13,24 @@ export default class App extends ModuleBase { * @returns Result of transaction. */ // FIXME(yoojin): need to fix getting function urls. - async create(appName: string, functionUrls: TriggerFunctionUrlMap, setDefaultFlag?: setDefaultFlag) { - if (!setDefaultFlag) - setDefaultFlag = { triggerFuncton: true }; + async create(appName: string, serviceUrl: string) { const setRuleOps: SetOperation[] = []; const setFunctionOps: SetOperation[] = []; const setBillingConfigOps: SetOperation[] = [] ; const createAppOp = this.buildCreateAppOp(appName); - const defaultRules = defaultAppRules(appName); + const defaultRules = this.defaultAppRules(appName); for (const rule of Object.values(defaultRules)) { const { ref, value } = rule; const ruleOp = buildSetOperation("SET_RULE", ref, value); setRuleOps.push(ruleOp); } - if (setDefaultFlag.triggerFuncton) { - const defaultFunctions = defaultAppFunctions(appName); - for (const [type, func] of Object.entries(defaultFunctions)) { - const { ref, function_id, function_type, function_url } = func(functionUrls[type]); - const value = this.buildSetFunctionValue({function_id, function_type, function_url}); - const funcOp = buildSetOperation("SET_FUNCTION", ref, value); - setFunctionOps.push(funcOp); - } - } - + const depositParam = this.depositTriggerFunctionConfig(appName, serviceUrl); + const value = this.buildSetFunctionValue(depositParam); + const funcOp = buildSetOperation("SET_FUNCTION", depositParam.ref, value); + setFunctionOps.push(funcOp); + const defaultConfig: appBillingConfig = { depositAddress: this.ain.wallet.defaultAccount!.address, service: { @@ -190,10 +81,9 @@ export default class App extends ModuleBase { */ async setTriggerFunctions(appName: string, functions: setTriggerFunctionParm[]) { const setFunctionOps: SetOperation[] = []; - for (const func of Object.values(functions)) { - const { ref } = func; - const value = this.buildSetFunctionValue(func); - const op = buildSetOperation("SET_FUNCTION", ref, value); + for (const param of Object.values(functions)) { + const value = this.buildSetFunctionValue(param); + const op = buildSetOperation("SET_FUNCTION", param.ref, value); setFunctionOps.push(op); } if (setFunctionOps.length <= 0) { @@ -288,4 +178,87 @@ export default class App extends ModuleBase { const value = !isRemoveOp ? null : true; return buildSetOperation("SET_VALUE", path, value); } + + private defaultAppRules = (appName: string): { [type: string]: { ref: string, value: object } } => { + const rootRef = Path.app(appName).root(); + return { + root: { + ref: rootRef, + value: { + ".rule": { + write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true" + } + } + }, + deposit: { + ref: `${Path.app(appName).depositOfUser("$userAddress")}/$transferKey`, + value: { + ".rule": { + write: "data === null && util.isNumber(newData) && getValue(`/transfer/` + $userAddress + `/` + getValue(`/apps/" + `${appName}` + "/billingConfig/depositAddress`) + `/` + $transferKey + `/value`) === newData" + } + } + }, + balance: { + ref: Path.app(appName).balanceOfUser("$userAddress"), + value: { + ".rule": { + write: "(util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true) && util.isNumber(newData)" + } + } + }, + balanceHistory: { + ref: `${rootRef}/balance/$userAddress/history/$timestamp_and_type`, + value: { + ".rule": { + write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && util.isNumber(newData.amount) && (newData.type === 'DEPOSIT' || newData.type === 'USAGE')" + } + } + }, + request: { + ref: Path.app(appName).request("$serviceName", "$userAddress", "$requestKey"), + value: { + ".rule": { + write: + "auth.addr === $userAddress && getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) !== null && " + + "((getValue(`/apps/" + `${appName}` + "/billingConfig/` + $serviceName) !== null) && (getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/` + $serviceName + `/minCost`)) || " + + "getValue(`/apps/" + `${appName}` + "/balance/` + $userAddress + `/balance`) >= getValue(`/apps/" + `${appName}` + "/billingConfig/service/default/minCost`)" + } + } + }, + response: { + ref: Path.app(appName).response("$serviceName", "userAddress", "$requestKey"), + value: { + ".rule": { + write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && util.isString(newData.status)" + } + }, + }, + billingConfig: { + ref: Path.app(appName).billingConfig(), + value: { + ".rule": { + write: "util.isAppAdmin(`" + `${appName}` + "`, auth.addr, getValue) === true && util.isDict(newData) && " + + "util.isString(newData.depositAddress) && util.isDict(newData.service) && util.isDict(newData.service.default)", + } + } + }, + billingConfigOfService: { + ref: Path.app(appName).billingConfigOfService("$serviceName"), + value: { + ".rule": { + write: "util.isAppAdmin(`" + `${appName}` + "`, auth,addr, getValue) === true && util.isDict(newData) && util.isNumber(newData.minCost)", + } + } + } + } + } + + private depositTriggerFunctionConfig = (appName: string, serviceUrl: string): setTriggerFunctionParm => { + return { + ref: `${Path.app(appName).depositOfUser("$userAddress")}/$transferKey`, + function_type: "REST", + function_id: "deposit-trigger", + function_url: `${serviceUrl}/deposit`, + } + } } diff --git a/src/types/type.ts b/src/types/type.ts index 4041af1..b16c174 100644 --- a/src/types/type.ts +++ b/src/types/type.ts @@ -1,24 +1,19 @@ -export type setDefaultFlag = { - triggerFuncton: boolean, -}; - -// NOTE(yoojin): pls suggest good name. export type triggerFunctionConfig = { - function_type: string, - function_url: string, - function_id: string, + function_type: string; + function_url: string; + function_id: string; }; export type setTriggerFunctionParm = { - ref: string + ref: string; } & triggerFunctionConfig; export type writeRuleConfig = { - write: string, + write: string; }; export type setRuleParam = { - ref: string + ref: string; } & writeRuleConfig; export type serviceBillingConfig = { @@ -41,9 +36,9 @@ export enum HISTORY_TYPE { } export type opResult = { - code: number, + code: number; bandwidth_gas_amount: number; - message?: string + message?: string; } export type txResult = {