Skip to content

Commit

Permalink
Add the ability to register a point provider
Browse files Browse the repository at this point in the history
  • Loading branch information
danial303065 authored and MichaelKim20 committed Aug 19, 2024
1 parent 2f51725 commit 95ccfec
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/relay/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ relay:
testMode: ${RELAY_TEST_MODE}
bridgeActiveStatus: true
allowedShopIdPrefix: "0x0001"
initialBalanceOfProvider: 50000

contracts:
sideChain:
Expand Down
1 change: 1 addition & 0 deletions packages/relay/config/config_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ relay:
testMode: ${RELAY_TEST_MODE}
bridgeActiveStatus: true
allowedShopIdPrefix: "0x0001"
initialBalanceOfProvider: 50000

contracts:
sideChain:
Expand Down
6 changes: 6 additions & 0 deletions packages/relay/src/common/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export class RelayConfig implements IRelayConfig {
public testMode: boolean;
public bridgeActiveStatus: boolean;
public allowedShopIdPrefix: string;
public initialBalanceOfProvider: number;

constructor() {
const defaults = RelayConfig.defaultValue();
Expand All @@ -228,6 +229,7 @@ export class RelayConfig implements IRelayConfig {
this.testMode = defaults.testMode;
this.bridgeActiveStatus = defaults.bridgeActiveStatus;
this.allowedShopIdPrefix = defaults.allowedShopIdPrefix;
this.initialBalanceOfProvider = defaults.initialBalanceOfProvider;
}

public static defaultValue(): IRelayConfig {
Expand All @@ -251,6 +253,7 @@ export class RelayConfig implements IRelayConfig {
testMode: false,
bridgeActiveStatus: true,
allowedShopIdPrefix: "0x0001",
initialBalanceOfProvider: 50000,
};
}

Expand All @@ -269,6 +272,8 @@ export class RelayConfig implements IRelayConfig {
if (config.bridgeActiveStatus !== undefined)
this.bridgeActiveStatus = config.bridgeActiveStatus.toString().toLowerCase() === "true";
if (config.allowedShopIdPrefix !== undefined) this.allowedShopIdPrefix = config.allowedShopIdPrefix;
if (config.initialBalanceOfProvider !== undefined)
this.initialBalanceOfProvider = config.initialBalanceOfProvider;
}
}

Expand Down Expand Up @@ -493,6 +498,7 @@ export interface IRelayConfig {
testMode: boolean;
bridgeActiveStatus: boolean;
allowedShopIdPrefix: string;
initialBalanceOfProvider: number;
}

export interface IContractsConfig {
Expand Down
50 changes: 50 additions & 0 deletions packages/relay/src/routers/ProviderRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,18 @@ export class ProviderRouter {
}

public registerRoutes() {
this.app.post(
"/v1/provider/register",
[
body("provider").exists().trim().isEthereumAddress(),
body("signature")
.exists()
.trim()
.matches(/^(0x)[0-9a-f]{130}$/i),
],
this.provider_register.bind(this)
);

this.app.get(
"/v1/provider/balance/:provider",
[param("provider").exists().trim().isEthereumAddress()],
Expand Down Expand Up @@ -148,6 +160,44 @@ export class ProviderRouter {
);
}

private async provider_register(req: express.Request, res: express.Response) {
logger.http(`POST /v1/provider/register ${req.ip}:${JSON.stringify(req.body)}`);

const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(200).json(ResponseMessage.getErrorMessage("2001", { validation: errors.array() }));
}

const signerItem = await this.getRelaySigner(this.contractManager.sideChainProvider);
try {
const provider: string = String(req.body.provider).trim();
const signature: string = String(req.body.signature).trim();

const nonce = await this.contractManager.sideLedgerContract.nonceOf(provider);
const message = ContractUtils.getRegisterProviderMessage(provider, nonce, this.contractManager.sideChainId);
if (!ContractUtils.verifyMessage(provider, message, signature))
return res.status(200).json(ResponseMessage.getErrorMessage("1501"));

const balance = await this.contractManager.sideLedgerContract.tokenBalanceOf(provider);
const minimum = BOACoin.make(this.config.relay.initialBalanceOfProvider).value;
if (balance.lt(minimum)) {
return res.status(200).json(ResponseMessage.getErrorMessage("1511"));
}

await this.storage.postNewProvider(provider);

this.metrics.add("success", 1);
return res.status(200).json(this.makeResponseData(0, { provider }));
} catch (error: any) {
const msg = ResponseMessage.getEVMErrorMessage(error);
logger.error(`POST /v1/provider/register : ${msg.error.message}`);
this.metrics.add("failure", 1);
return res.status(200).json(this.makeResponseData(msg.code, undefined, msg.error));
} finally {
this.releaseRelaySigner(signerItem);
}
}

private async provider_balance(req: express.Request, res: express.Response) {
logger.http(`GET /v1/provider/balance/:provider ${req.ip}:${JSON.stringify(req.params)}`);

Expand Down
15 changes: 15 additions & 0 deletions packages/relay/src/storage/RelayStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -980,4 +980,19 @@ export class RelayStorage extends Storage {
});
}
/// endregion

public postNewProvider(provider: string): Promise<void> {
return new Promise<void>(async (resolve, reject) => {
this.queryForMapper("register_provider", "postProvider", {
provider,
})
.then(() => {
return resolve();
})
.catch((reason) => {
if (reason instanceof Error) return reject(reason);
return reject(new Error(reason));
});
});
}
}
30 changes: 30 additions & 0 deletions packages/relay/src/storage/mapper/register_provider.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="register_provider">

<insert id="postProvider">
INSERT INTO register_provider
(
"provider" ,
"timestamp"
)
VALUES
(
#{provider} ,
now()
)
ON CONFLICT ("sequence")
DO UPDATE
SET
"provider" = EXCLUDED."provider",
"timestamp" = EXCLUDED."timestamp";
</insert>

<select id="read">
SELECT * FROM register_provider;
</select>

<select id="remove">
DELETE FROM register_provider WHERE sequence = ${sequence};
</select>
</mapper>
16 changes: 16 additions & 0 deletions packages/relay/src/storage/mapper/table.xml
Original file line number Diff line number Diff line change
Expand Up @@ -113,13 +113,28 @@

</sql>

<sql id="register_provider">
CREATE TABLE IF NOT EXISTS register_provider
(
"sequence" BIGINT generated always as identity,
"provider" VARCHAR(42) NOT NULL,
"timestamp" TIMESTAMP,
PRIMARY KEY ("sequence")
);
CREATE SEQUENCE IF NOT EXISTS register_provider_sequence_seq;
CREATE INDEX IF NOT EXISTS register_provider_provider_index
on register_provider (provider);

</sql>

<select id="create_table">
<include refid="payments"/>
<include refid="tasks"/>
<include refid="mobiles"/>
<include refid="purchase"/>
<include refid="delegators"/>
<include refid="temporary_accounts"/>
<include refid="register_provider"/>
</select>

<select id="drop_table">
Expand All @@ -129,6 +144,7 @@
DROP TABLE purchases;
DROP TABLE delegators;
DROP TABLE temporary_accounts;
DROP TABLE register_provider;
</select>

</mapper>
5 changes: 5 additions & 0 deletions packages/relay/src/utils/ContractUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,11 @@ export class ContractUtils {
return arrayify(keccak256(encodedResult));
}

public static getRegisterProviderMessage(provider: string, nonce: BigNumberish, chainId: BigNumberish): Uint8Array {
const encodedResult = defaultAbiCoder.encode(["address", "uint256", "uint256"], [provider, chainId, nonce]);
return arrayify(keccak256(encodedResult));
}

public static async signMessage(signer: Signer, message: Uint8Array): Promise<string> {
return signer.signMessage(message);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/relay/src/utils/Errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,11 @@ export class ResponseMessage {
["2003", "The payment ID is not exist"],
["2004", "Temporary address that does not exist"],
["2005", "Mobile notification not allowed"],
["2006", "Can not found delegator"],
["2006", "Can not find delegator"],
["2007", "The phone number format is invalid."],
["2008", "Mobile information not found."],
["2020", "The status code for this payment cannot be approved"],
["2022", "The status code for this payment cannot be cancel"],
["2022", "The status code for this payment cannot be cancelled"],
["2024", "The status code for this payment cannot process closing"],
["2025", "This payment has already been approved"],
["2026", "This payment has already been closed"],
Expand Down

0 comments on commit 95ccfec

Please sign in to comment.