@prosopo/provider 0.1.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.dockerignore ADDED
@@ -0,0 +1,5 @@
1
+ node_modules/
2
+ dist/
3
+ .env*
4
+ .git/
5
+ .cache/
package/Dockerfile ADDED
@@ -0,0 +1,12 @@
1
+ FROM node:16
2
+
3
+ WORKDIR /usr/src/app
4
+
5
+ COPY . ./
6
+
7
+ RUN npm i
8
+ RUN npm run build:config -- ./tsconfig.docker.json
9
+
10
+ EXPOSE 3000
11
+
12
+ ENTRYPOINT [ "npm", "run", "serve" ]
package/README.md ADDED
@@ -0,0 +1,259 @@
1
+ # Prosopo Provider
2
+
3
+ > NOTE: For a development environment, the easiest way to deploy the Prosopo contract and run the Provider node is via the [integration repository](https://github.com/prosopo/integration/). The following instructions explain how to set up the repositories manually.
4
+
5
+ ## Prerequisites
6
+
7
+ - nodejs
8
+ - npm
9
+ - A connection to a substrate node
10
+ - A deployed Prosopo Protocol contract
11
+
12
+
13
+ ### Development Environment
14
+ #### Setup a contract node
15
+
16
+ If you are setting up a development environment, run a development node. For example, the [Substrate Contracts Node](https://github.com/paritytech/substrate-contracts-node/#installation)
17
+
18
+ #### Deploy the Prosopo Protocol contract
19
+
20
+ See [protocol instructions](https://github.com/prosopo/protocol/#prosopo-protocol)
21
+
22
+ #### Live environment
23
+ If you are running in a test or live environment, use a node endpoint of your choice. Make sure you know the contract account of the Prosopo Protocol contract.
24
+
25
+
26
+ ## Running a Prosopo Provider Node
27
+
28
+ The following instructions apply to the `provider` repo.
29
+
30
+ ### Install packages
31
+
32
+ ```bash
33
+ npm install
34
+ ```
35
+
36
+ ### Populate the Prosopo Provider Config
37
+
38
+ Place the required variables in the `prosopo.config.ts` file in the root of the `provider` repo.
39
+
40
+ | Param | Description |
41
+ |------------------------------------------|--------------------------------------------------------------------------------|
42
+ | PROTOCOL_CONTRACT_JSON_ABI_PATH | The path to the protocol JSON file |
43
+ | SUBSTATE_NODE_ENDPOINT | The substrate node endpoint, e.g. ws://localhost:9944 |
44
+ | PROTOCOL_CONTRACT_ADDRESS | The protocol contract address |
45
+ | CAPTCHA_SOLVED_COUNT | The number of solved captchas to send to the captcha frontend client |
46
+ | CAPTCHA_UNSOLVED_COUNT | The number of unsolved captchas to send to the captcha frontend client |
47
+ | CAPTCHA_SOLUTION_REQUIRED_SOLUTION_COUNT | The number of captchas required to calculate a solution to an unsolved captcha |
48
+ | CAPTCHA_SOLUTION_WINNING_PERCENTAGE | The threshold percentage that determines whether a solution is found |
49
+ | CAPTCHA_FILE_PATH | The path to the captcha dataset |
50
+ | MONGO_USERNAME | MongoDB username |
51
+ | MONGO_PASSWORD | MongoDB password |
52
+ | MONGO_HOST | MongoDB host |
53
+ | MONGO_PORT | MongoDB port |
54
+ | DATABASE_NAME | Database name |
55
+ | API_BASE_URL | Base URL for API, e.g. http://localhost:3000 |
56
+
57
+ #### Config
58
+
59
+ ```typescript
60
+ const config = {
61
+ contract: {
62
+ abi: '<PROTOCOL_CONTRACT_JSON_ABI_PATH>'
63
+ },
64
+ networks: {
65
+ development: {
66
+ endpoint: '<SUBSTATE_NODE_ENDPOINT>', // e.g. ws://127.0.0.1:9944
67
+ contract: {
68
+ address: '<PROTOCOL_CONTRACT_ADDRESS>',
69
+ name: 'prosopo'
70
+ }
71
+ }
72
+ },
73
+ captchas: {
74
+ solved: {
75
+ count: '<CAPTCHA_SOLVED_COUNT>'
76
+ },
77
+ unsolved: {
78
+ count: '<CAPTCHA_UNSOLVED_COUNT>'
79
+ }
80
+ },
81
+ captchaSolutions: {
82
+ requiredNumberOfSolutions: '<CAPTCHA_SOLUTION_REQUIRED_SOLUTION_COUNT>',
83
+ solutionWinningPercentage: '<CAPTCHA_SOLUTION_WINNING_PERCENTAGE>',
84
+ captchaFilePath: '<CAPTCHA_FILE_PATH>',
85
+ },
86
+ database: {
87
+ development: {
88
+ storageType: 'mongo',
89
+ endpoint: `mongodb://<MONGO_USERNAME>:<MONGO_PASSWORD>@<MONGO_HOST>:<MONGO_PORT>`,
90
+ dbname: '<DATABASE_NAME>',
91
+ }
92
+ },
93
+ assets: {
94
+ absolutePath: '',
95
+ basePath: ''
96
+ },
97
+ server: {
98
+ baseURL: '<API_BASE_URL>',
99
+ }
100
+ }
101
+ ```
102
+
103
+ ## Run the Provider server
104
+
105
+ ### Set a provider mnemonic in prosopo.config.js
106
+
107
+ > Please note your `PROVIDER_MNEMONIC` environment variable must be set. You can check this with `echo $PROVIDER_MNEMONIC`
108
+
109
+ In a **development environment**, it's easiest to use a development mnemonic as they already have funds. So choose one of //Alice, //Bob, //Ferdie, etc.
110
+
111
+ ```bash
112
+ export PROVIDER_MNEMONIC=//Ferdie
113
+ ```
114
+
115
+ You can now register as a Provider in the protocol contract either via the command line.
116
+
117
+ ### Register using the Command Line
118
+
119
+ Try registering a provider on the command line.
120
+
121
+ ```bash
122
+ npm run cli provider_register -- \
123
+ --fee 10 \
124
+ --origin https://localhost:9229 \
125
+ --payee Provider \
126
+ --address YOUR_PROVIDER_ADDRESS
127
+ ````
128
+
129
+ Send a stake (`value`) and/or update one of the values previously set when registering (`fee`, `origin`. `payee`).
130
+
131
+ ```bash
132
+ npm run cli provider_update -- \
133
+ --fee 10 \
134
+ --origin https://localhost:9229 \
135
+ --payee Provider \
136
+ --address YOUR_PROVIDER_ADDRESS \
137
+ --value 10
138
+ ```
139
+
140
+ Verify that your provider was registered by calling the `/v1/prosopo/providers/` endpoint or by checking in Polkadot Apps local node.
141
+
142
+ ### Curl
143
+ ```
144
+ curl --location --request GET '127.0.0.1:3000/v1/prosopo/providers/'
145
+ {"accounts":["YOUR PROVIDER ADDRESS"]}
146
+ ```
147
+
148
+ ### Polkadot Apps
149
+ Using [Polkadot apps](https://polkadot.js.org/apps/?rpc=ws%3A%2F%2F127.0.0.1%3A9944#/contracts)
150
+
151
+ 1. Click Add an existing contract
152
+ 2. Enter the contract address and click to select the `prosopo.json` file in the artifacts folder as the `contract ABI`
153
+ 3. Expand the contract to see the current value of `getProviders`. It should be `["YOUR PROVIDER ADDRESS"]`.
154
+
155
+
156
+ ## Command Line Interface
157
+
158
+ > Please note your `PROVIDER_MNEMONIC` environment variable must be set. You can check this with `echo $PROVIDER_MNEMONIC`
159
+
160
+ ### Register a provider
161
+
162
+ ```bash
163
+ npm run cli -- provider_register --fee=10 --origin=https://localhost:9229 --payee=Provider --address ADDRESS
164
+ ```
165
+
166
+ | Param | Description |
167
+ |---------|----------------------------------------------------------------------------|
168
+ | fee | The amount the Provider charges or pays per captcha approval / disapproval |
169
+ | origin | The location of the Provider's service |
170
+ | payee | Who is paid on successful captcha completion (`Provider` or `Dapp`) |
171
+ | address | Address of the Provider |
172
+
173
+ ### Update a provider and optionally stake
174
+
175
+ ```bash
176
+ npm run cli -- provider_update --fee=10 --origin=https://localhost:9229 --payee=Provider --address ADDRESS --value STAKE_VALUE
177
+ ```
178
+
179
+ Params are the same as `provider_register` with the addition of `value`
180
+
181
+ | Param | Description |
182
+ | --------------- | --------------- |
183
+ | value | The amount of funds to stake in the contract |
184
+
185
+
186
+ ### Add a dataset for a Provider
187
+
188
+ ```bash
189
+ npm run cli -- provider_add_data_set --file /usr/src/data/captchas.json
190
+ ```
191
+
192
+ | Param | Description |
193
+ | --------------- | --------------- |
194
+ | file | JSON file containing captchas |
195
+
196
+ File format can be viewed [here](https://github.com/prosopo/provider/blob/master/tests/mocks/data/captchas.json).
197
+
198
+ ### De-register a Provider
199
+
200
+ ```bash
201
+ npm run cli -- provider_deregister --address ADDRESS
202
+ ```
203
+
204
+ | Param | Description |
205
+ | --------------- | --------------- |
206
+ | address | Address of the Provider |
207
+
208
+ ### Unstake funds
209
+
210
+ ```bash
211
+ npm run cli -- provider_unstake --value VALUE
212
+ ```
213
+
214
+ | Param | Description |
215
+ | --------------- | --------------- |
216
+ | value | The amount of funds to unstake from the contract |
217
+
218
+ ### List Provider accounts in contract
219
+
220
+ ```bash
221
+ npm run cli -- provider_accounts
222
+ ```
223
+
224
+ ### Other commands ###
225
+
226
+ A full list of CLI commands can be viewed by running
227
+
228
+ ```bash
229
+ npm run cli -- --help
230
+ ```
231
+
232
+ ## API
233
+
234
+ Run the Provider API server and image server
235
+
236
+ ```bash
237
+ npm run start
238
+ ```
239
+
240
+ The API contains methods required by the frontend captcha interface.
241
+
242
+ | API Resource | Function | Type | Parameters |
243
+ |------------------------------------------------------------------------------------------|--------------------------------------------|------|--------------------------------------------------------------------|
244
+ | `/v1/prosopo/random_provider/:userAccount/:dappContractAccount` | Get a random provider based on AccountId | GET | userAccount, dappContractAccount |
245
+ | `/v1/prosopo/providers/` | Get list of all provider IDs | GET | |
246
+ | `/v1/prosopo/dapps/` | Get list of all dapp IDs | GET | |
247
+ | `/v1/prosopo/provider/:providerAccount` | Get details of a specific Provider account | GET | providerAccount |
248
+ | `/v1/prosopo/provider/captcha/:datasetId/:userAccount/:dappContractAccount/:blockNumber` | Get captchas to solve | GET | datasetId, userAccount, dappContractAccount, blockNumber |
249
+ | `/v1/prosopo/provider/solution` | Submit captcha solutions | POST | userAccount, dappAccount, requestHash, captchas, blockHash, txHash |
250
+
251
+ ## Tests
252
+
253
+ You can run the Provider integration tests using the command `npm run test`. This will start a substrate container containing a predeployed [prosopo protocol contract](https://github.com/prosopo/protocol/#prosopo-protocol) and [dapp-example contract](https://github.com/prosopo/dapp-example#dapp-example). An in-memory mongo database will be used.
254
+
255
+ To run the tests with coverage stats use:
256
+
257
+ ```bash
258
+ npx c8 npm run test
259
+ ```
package/dist/api.d.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { ProviderEnvironment } from '@prosopo/types-env';
2
+ import { Router } from 'express';
3
+ /**
4
+ * Returns a router connected to the database which can interact with the Proposo protocol
5
+ *
6
+ * @return {Router} - A middleware router that can interact with the Prosopo protocol
7
+ * @param {Environment} env - The Prosopo environment
8
+ */
9
+ export declare function prosopoRouter(env: ProviderEnvironment): Router;
10
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAMxD,OAAgB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAEzC;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,mBAAmB,GAAG,MAAM,CAiH9D"}
package/dist/api.js ADDED
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prosopoRouter = void 0;
4
+ const tslib_1 = require("tslib");
5
+ // Copyright 2021-2022 Prosopo (UK) Ltd.
6
+ //
7
+ // Licensed under the Apache License, Version 2.0 (the "License");
8
+ // you may not use this file except in compliance with the License.
9
+ // You may obtain a copy of the License at
10
+ //
11
+ // http://www.apache.org/licenses/LICENSE-2.0
12
+ //
13
+ // Unless required by applicable law or agreed to in writing, software
14
+ // distributed under the License is distributed on an "AS IS" BASIS,
15
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ // See the License for the specific language governing permissions and
17
+ // limitations under the License.
18
+ const types_1 = require("@prosopo/types");
19
+ const types_2 = require("@prosopo/types");
20
+ const common_1 = require("@prosopo/common");
21
+ const tasks_1 = require("./tasks/tasks");
22
+ const util_1 = require("./util");
23
+ const datasets_1 = require("@prosopo/datasets");
24
+ const util_crypto_1 = require("@polkadot/util-crypto");
25
+ const express_1 = tslib_1.__importDefault(require("express"));
26
+ /**
27
+ * Returns a router connected to the database which can interact with the Proposo protocol
28
+ *
29
+ * @return {Router} - A middleware router that can interact with the Prosopo protocol
30
+ * @param {Environment} env - The Prosopo environment
31
+ */
32
+ function prosopoRouter(env) {
33
+ const router = express_1.default.Router();
34
+ const tasks = new tasks_1.Tasks(env);
35
+ /**
36
+ * Provides a Captcha puzzle to a Dapp User
37
+ * @param {string} datasetId - Provider datasetId
38
+ * @param {string} userAccount - Dapp User AccountId
39
+ * @param {string} blockNumber - Block number
40
+ * @return {Captcha} - The Captcha data
41
+ */
42
+ router.get(`${types_1.ApiPaths.GetCaptchaChallenge}/:${types_1.ApiParams.datasetId}/:${types_1.ApiParams.user}/:${types_1.ApiParams.dapp}/:${types_1.ApiParams.blockNumber}`, async (req, res, next) => {
43
+ try {
44
+ const { blockNumber, datasetId, user, dapp } = types_2.CaptchaRequestBody.parse(req.params);
45
+ (0, util_crypto_1.validateAddress)(user, false, env.api.registry.chainSS58);
46
+ const blockNumberParsed = (0, util_1.parseBlockNumber)(blockNumber);
47
+ await tasks.validateProviderWasRandomlyChosen(user, dapp, datasetId, blockNumberParsed);
48
+ const taskData = await tasks.getRandomCaptchasAndRequestHash(datasetId, user);
49
+ taskData.captchas = taskData.captchas.map((cwp) => ({
50
+ ...cwp,
51
+ captcha: {
52
+ ...cwp.captcha,
53
+ items: cwp.captcha.items.map((item) => (0, datasets_1.parseCaptchaAssets)(item, env.assetsResolver)),
54
+ },
55
+ }));
56
+ return res.json(taskData);
57
+ }
58
+ catch (err) {
59
+ return next(new common_1.ProsopoApiError(err, undefined, 400));
60
+ }
61
+ });
62
+ /**
63
+ * Receives solved CAPTCHA challenges, store to database, and check against solution commitment
64
+ *
65
+ * @param {string} userAccount - Dapp User id
66
+ * @param {string} dappAccount - Dapp Contract AccountId
67
+ * @param {Captcha[]} captchas - The Captcha solutions
68
+ * @return {DappUserSolutionResult} - The Captcha solution result and proof
69
+ */
70
+ router.post(types_1.ApiPaths.SubmitCaptchaSolution, async (req, res, next) => {
71
+ let parsed;
72
+ try {
73
+ parsed = types_1.CaptchaSolutionBody.parse(req.body);
74
+ }
75
+ catch (err) {
76
+ return next(new common_1.ProsopoApiError(err, undefined, 400));
77
+ }
78
+ try {
79
+ const result = await tasks.dappUserSolution(parsed[types_1.ApiParams.user], parsed[types_1.ApiParams.dapp], parsed[types_1.ApiParams.requestHash], parsed[types_1.ApiParams.captchas], parsed[types_1.ApiParams.signature]);
80
+ return res.json({
81
+ status: req.i18n.t(result.solutionApproved ? 'API.CAPTCHA_PASSED' : 'API.CAPTCHA_FAILED'),
82
+ ...result,
83
+ });
84
+ }
85
+ catch (err) {
86
+ return next(new common_1.ProsopoApiError(err, undefined, 400));
87
+ }
88
+ });
89
+ /**
90
+ * Verifies a user's solution as being approved or not
91
+ *
92
+ * @param {string} userAccount - Dapp User id
93
+ * @param {string} commitmentId - The captcha solution to look up
94
+ */
95
+ router.post(types_1.ApiPaths.VerifyCaptchaSolution, async (req, res, next) => {
96
+ let parsed;
97
+ try {
98
+ parsed = types_1.VerifySolutionBody.parse(req.body);
99
+ }
100
+ catch (err) {
101
+ return next(new common_1.ProsopoApiError(err, undefined, 400));
102
+ }
103
+ try {
104
+ let solution;
105
+ let statusMessage = 'API.USER_NOT_VERIFIED';
106
+ if (!parsed.commitmentId) {
107
+ solution = await tasks.getDappUserCommitmentByAccount(parsed.user);
108
+ }
109
+ else {
110
+ solution = await tasks.getDappUserCommitmentById(parsed.commitmentId);
111
+ }
112
+ if (solution) {
113
+ let approved = false;
114
+ if (solution.status === types_1.CaptchaStatus.approved) {
115
+ statusMessage = 'API.USER_VERIFIED';
116
+ approved = true;
117
+ }
118
+ return res.json({
119
+ status: req.t(statusMessage),
120
+ solutionApproved: approved,
121
+ commitmentId: solution.id,
122
+ });
123
+ }
124
+ return res.json({
125
+ status: req.t(statusMessage),
126
+ solutionApproved: false,
127
+ });
128
+ }
129
+ catch (err) {
130
+ return next(new common_1.ProsopoApiError(err, undefined, 400));
131
+ }
132
+ });
133
+ return router;
134
+ }
135
+ exports.prosopoRouter = prosopoRouter;
136
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":";;;;AAAA,wCAAwC;AACxC,EAAE;AACF,kEAAkE;AAClE,mEAAmE;AACnE,0CAA0C;AAC1C,EAAE;AACF,iDAAiD;AACjD,EAAE;AACF,sEAAsE;AACtE,oEAAoE;AACpE,2EAA2E;AAC3E,sEAAsE;AACtE,iCAAiC;AACjC,0CAQuB;AACvB,0CAAmD;AAEnD,4CAAiD;AAEjD,yCAAqC;AAErC,iCAAyC;AACzC,gDAAsD;AACtD,uDAAuD;AACvD,8DAAyC;AAEzC;;;;;GAKG;AACH,SAAgB,aAAa,CAAC,GAAwB;IAClD,MAAM,MAAM,GAAG,iBAAO,CAAC,MAAM,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAG,IAAI,aAAK,CAAC,GAAG,CAAC,CAAA;IAE5B;;;;;;OAMG;IACH,MAAM,CAAC,GAAG,CACN,GAAG,gBAAQ,CAAC,mBAAmB,KAAK,iBAAS,CAAC,SAAS,KAAK,iBAAS,CAAC,IAAI,KAAK,iBAAS,CAAC,IAAI,KAAK,iBAAS,CAAC,WAAW,EAAE,EACzH,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACrB,IAAI;YACA,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,0BAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YAEnF,IAAA,6BAAe,EAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;YACxD,MAAM,iBAAiB,GAAG,IAAA,uBAAgB,EAAC,WAAW,CAAC,CAAA;YAEvD,MAAM,KAAK,CAAC,iCAAiC,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAA;YAEvF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,+BAA+B,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;YAC7E,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAqB,EAAE,EAAE,CAAC,CAAC;gBAClE,GAAG,GAAG;gBACN,OAAO,EAAE;oBACL,GAAG,GAAG,CAAC,OAAO;oBACd,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,6BAAkB,EAAC,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;iBACvF;aACJ,CAAC,CAAC,CAAA;YACH,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;SAC5B;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,IAAI,wBAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;SACxD;IACL,CAAC,CACJ,CAAA;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,IAAI,CAAC,gBAAQ,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjE,IAAI,MAA+B,CAAA;QACnC,IAAI;YACA,MAAM,GAAG,2BAAmB,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;SAC/C;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,IAAI,wBAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;SACxD;QAED,IAAI;YACA,MAAM,MAAM,GAA2B,MAAM,KAAK,CAAC,gBAAgB,CAC/D,MAAM,CAAC,iBAAS,CAAC,IAAI,CAAC,EACtB,MAAM,CAAC,iBAAS,CAAC,IAAI,CAAC,EACtB,MAAM,CAAC,iBAAS,CAAC,WAAW,CAAC,EAC7B,MAAM,CAAC,iBAAS,CAAC,QAAQ,CAAC,EAC1B,MAAM,CAAC,iBAAS,CAAC,SAAS,CAAC,CAC9B,CAAA;YACD,OAAO,GAAG,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC;gBACzF,GAAG,MAAM;aACZ,CAAC,CAAA;SACL;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,IAAI,wBAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;SACxD;IACL,CAAC,CAAC,CAAA;IAEF;;;;;OAKG;IACH,MAAM,CAAC,IAAI,CAAC,gBAAQ,CAAC,qBAAqB,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACjE,IAAI,MAA8B,CAAA;QAClC,IAAI;YACA,MAAM,GAAG,0BAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;SAC9C;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,IAAI,wBAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;SACxD;QACD,IAAI;YACA,IAAI,QAA0C,CAAA;YAC9C,IAAI,aAAa,GAAG,uBAAuB,CAAA;YAC3C,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE;gBACtB,QAAQ,GAAG,MAAM,KAAK,CAAC,8BAA8B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;aACrE;iBAAM;gBACH,QAAQ,GAAG,MAAM,KAAK,CAAC,yBAAyB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAA;aACxE;YACD,IAAI,QAAQ,EAAE;gBACV,IAAI,QAAQ,GAAG,KAAK,CAAA;gBACpB,IAAI,QAAQ,CAAC,MAAM,KAAK,qBAAa,CAAC,QAAQ,EAAE;oBAC5C,aAAa,GAAG,mBAAmB,CAAA;oBACnC,QAAQ,GAAG,IAAI,CAAA;iBAClB;gBACD,OAAO,GAAG,CAAC,IAAI,CAAC;oBACZ,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC;oBAC5B,gBAAgB,EAAE,QAAQ;oBAC1B,YAAY,EAAE,QAAQ,CAAC,EAAE;iBAC5B,CAAC,CAAA;aACL;YACD,OAAO,GAAG,CAAC,IAAI,CAAC;gBACZ,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC;gBAC5B,gBAAgB,EAAE,KAAK;aAC1B,CAAC,CAAA;SACL;QAAC,OAAO,GAAG,EAAE;YACV,OAAO,IAAI,CAAC,IAAI,wBAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,CAAC,CAAC,CAAA;SACxD;IACL,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACjB,CAAC;AAjHD,sCAiHC"}
@@ -0,0 +1,24 @@
1
+ /// <reference types="bn.js" />
2
+ import { ArgumentTypes, Commit } from '@prosopo/types';
3
+ import { BN } from '@polkadot/util';
4
+ import { BatchCommitConfig, ExtrinsicBatch } from '@prosopo/types';
5
+ import { Database, UserCommitmentRecord } from '@prosopo/types-database';
6
+ import { Logger } from '@prosopo/common';
7
+ import { ProsopoCaptchaContract } from '@prosopo/contract';
8
+ import { WeightV2 } from '@polkadot/types/interfaces';
9
+ export declare class BatchCommitments {
10
+ contract: ProsopoCaptchaContract;
11
+ db: Database;
12
+ batchCommitConfig: BatchCommitConfig;
13
+ logger: Logger;
14
+ private nonce;
15
+ constructor(batchCommitConfig: BatchCommitConfig, contractApi: ProsopoCaptchaContract, db: Database, concurrent: number, startNonce: bigint, logger: Logger);
16
+ runBatch(): Promise<void>;
17
+ createExtrinsics(commitments: UserCommitmentRecord[]): Promise<ExtrinsicBatch>;
18
+ extrinsicTooHigh(totalRefTime: BN, totalProofSize: BN, maxBlockWeight: WeightV2): boolean;
19
+ batchIntervalExceeded(): Promise<boolean>;
20
+ getCommitments(): Promise<UserCommitmentRecord[]>;
21
+ removeCommitmentsAndSolutions(commitmentIds: ArgumentTypes.Hash[]): Promise<void>;
22
+ convertCommit(commitment: UserCommitmentRecord): Commit;
23
+ }
24
+ //# sourceMappingURL=commitments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commitments.d.ts","sourceRoot":"","sources":["../../src/batch/commitments.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AACnC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAA2C,MAAM,gBAAgB,CAAA;AAC3G,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAA;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,sBAAsB,EAA0D,MAAM,mBAAmB,CAAA;AAElH,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAMrD,qBAAa,gBAAgB;IACzB,QAAQ,EAAE,sBAAsB,CAAA;IAChC,EAAE,EAAE,QAAQ,CAAA;IACZ,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,KAAK,CAAQ;gBAEjB,iBAAiB,EAAE,iBAAiB,EACpC,WAAW,EAAE,sBAAsB,EACnC,EAAE,EAAE,QAAQ,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM;IAQZ,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAiDzB,gBAAgB,CAAC,WAAW,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAkFpF,gBAAgB,CAAC,YAAY,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,cAAc,EAAE,QAAQ,GAAG,OAAO;IAOnF,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IAMzC,cAAc,IAAI,OAAO,CAAC,oBAAoB,EAAE,CAAC;IAKjD,6BAA6B,CAAC,aAAa,EAAE,aAAa,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvF,aAAa,CAAC,UAAU,EAAE,oBAAoB,GAAG,MAAM;CAY1D"}
@@ -0,0 +1,150 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BatchCommitments = void 0;
4
+ const util_1 = require("@polkadot/util");
5
+ const types_1 = require("@prosopo/types");
6
+ const contract_1 = require("@prosopo/contract");
7
+ const util_crypto_1 = require("@polkadot/util-crypto");
8
+ const BN_TEN_THOUSAND = new util_1.BN(10_000);
9
+ const CONTRACT_METHOD_NAME = 'providerCommitMany';
10
+ class BatchCommitments {
11
+ contract;
12
+ db;
13
+ batchCommitConfig;
14
+ logger;
15
+ nonce;
16
+ constructor(batchCommitConfig, contractApi, db, concurrent, startNonce, logger) {
17
+ this.contract = contractApi;
18
+ this.db = db;
19
+ this.batchCommitConfig = batchCommitConfig;
20
+ this.logger = logger;
21
+ this.nonce = startNonce;
22
+ }
23
+ async runBatch() {
24
+ // create a task id
25
+ const taskId = (0, util_crypto_1.randomAsHex)(32);
26
+ if (await this.batchIntervalExceeded()) {
27
+ try {
28
+ // update last commit time
29
+ await this.db.storeScheduledTaskStatus(taskId, types_1.ScheduledTaskNames.BatchCommitment, types_1.ScheduledTaskStatus.Running);
30
+ //get commitments
31
+ const commitments = await this.getCommitments();
32
+ if (commitments.length > 0) {
33
+ this.logger.info(`Found ${commitments.length} commitments to commit`);
34
+ // get the extrinsics that are to be batched and an id associated with each one
35
+ const { extrinsics, ids: commitmentIds } = await this.createExtrinsics(commitments);
36
+ // commit and get the Ids of the commitments that were committed on-chain
37
+ await (0, contract_1.batch)(this.contract.contract, this.contract.pair, extrinsics, this.logger);
38
+ // remove commitments
39
+ await this.removeCommitmentsAndSolutions(commitmentIds);
40
+ // update last commit time and store the commitmentIds that were batched
41
+ await this.db.storeScheduledTaskStatus(taskId, types_1.ScheduledTaskNames.BatchCommitment, types_1.ScheduledTaskStatus.Completed, {
42
+ data: {
43
+ commitmentIds: commitments
44
+ .filter((commitment) => commitmentIds.indexOf(commitment.id) > -1)
45
+ .map((c) => c.id),
46
+ },
47
+ });
48
+ }
49
+ }
50
+ catch (e) {
51
+ this.logger.error(e);
52
+ await this.db.storeScheduledTaskStatus(taskId, types_1.ScheduledTaskNames.BatchCommitment, types_1.ScheduledTaskStatus.Failed, {
53
+ error: JSON.stringify(e && e.message ? e.message : e),
54
+ });
55
+ }
56
+ }
57
+ }
58
+ async createExtrinsics(commitments) {
59
+ const txs = [];
60
+ const fragment = this.contract.abi.findMessage(CONTRACT_METHOD_NAME);
61
+ const batchedCommitmentIds = [];
62
+ let totalRefTime = new util_1.BN(0);
63
+ let totalProofSize = new util_1.BN(0);
64
+ let totalFee = new util_1.BN(0);
65
+ const maxBlockWeight = this.contract.api.consts.system.blockWeights.maxBlock;
66
+ const commitmentArray = [];
67
+ let extrinsic;
68
+ for (const commitment of commitments) {
69
+ const commit = this.convertCommit(commitment);
70
+ commitmentArray.push(commit);
71
+ const encodedArgs = (0, contract_1.encodeStringArgs)(this.contract.abi, fragment, [commitmentArray]);
72
+ // TODO can we get storage deposit from the provided query method?
73
+ // https://matrix.to/#/!utTuYglskDvqRRMQta:matrix.org/$tELySFxCORlHCHveOknGJBx-MdVe-SxFN8_BsYvcDmI?via=matrix.org&via=t2bot.io&via=cardinal.ems.host
74
+ // const response = await this.contract.query.providerCommitMany(commitmentArray)
75
+ const buildExtrinsicResult = await this.contract.getExtrinsicAndGasEstimates('providerCommitMany', encodedArgs);
76
+ extrinsic = buildExtrinsicResult.extrinsic;
77
+ const { options, storageDeposit } = buildExtrinsicResult;
78
+ let paymentInfo;
79
+ try {
80
+ paymentInfo = (await extrinsic.paymentInfo(this.contract.pair)).partialFee.toBn();
81
+ this.logger.debug(`${CONTRACT_METHOD_NAME} paymentInfo:`, paymentInfo.toNumber());
82
+ }
83
+ catch (e) {
84
+ // TODO https://github.com/polkadot-js/api/issues/5504
85
+ paymentInfo = new util_1.BN(0);
86
+ }
87
+ //totalEncodedLength += extrinsic.encodedLength
88
+ totalRefTime = totalRefTime.add(this.contract.api.registry.createType('WeightV2', options.gasLimit).refTime.toBn());
89
+ totalProofSize = totalProofSize.add(this.contract.api.registry.createType('WeightV2', options.gasLimit).proofSize.toBn());
90
+ totalFee = totalFee.add(paymentInfo.add(storageDeposit.asCharge.toBn()));
91
+ const extrinsicTooHigh = this.extrinsicTooHigh(totalRefTime, totalProofSize, maxBlockWeight);
92
+ this.logger.debug('Free balance', '`', (await this.contract.api.query.system.account(this.contract.pair.address)).data.free
93
+ .toBn()
94
+ .div((0, contract_1.oneUnit)(this.contract.api))
95
+ .toString(), '`', 'UNIT');
96
+ this.logger.debug('Total Fee `', totalFee.div((0, contract_1.oneUnit)(this.contract.api)).toString(), '`', 'UNIT');
97
+ const feeTooHigh = totalFee.gt((await this.contract.api.query.system.account(this.contract.pair.address)).data.free.toBn());
98
+ // Check if we have a maximum number of transactions that we can successfully submit in a block or if the
99
+ // total fee is more than the provider has left in their account
100
+ if (extrinsicTooHigh || feeTooHigh) {
101
+ const msg = extrinsicTooHigh ? 'Max batch extrinsic percentage reached' : 'Fee too high';
102
+ this.logger.warn(msg);
103
+ break;
104
+ }
105
+ else {
106
+ batchedCommitmentIds.push(commitment.id);
107
+ }
108
+ }
109
+ if (!extrinsic) {
110
+ throw new contract_1.ProsopoContractError('No extrinsics created');
111
+ }
112
+ txs.push(extrinsic);
113
+ this.logger.info(`${txs.length} transactions will be batched`);
114
+ this.logger.debug('totalRefTime:', totalRefTime.toString());
115
+ this.logger.debug('totalProofSize:', totalProofSize.toString());
116
+ return { extrinsics: txs, ids: batchedCommitmentIds, totalFee, totalRefTime, totalProofSize };
117
+ }
118
+ extrinsicTooHigh(totalRefTime, totalProofSize, maxBlockWeight) {
119
+ return (totalRefTime.mul(BN_TEN_THOUSAND).div(maxBlockWeight.refTime.toBn()).toNumber() / 100 >
120
+ this.batchCommitConfig.maxBatchExtrinsicPercentage);
121
+ }
122
+ async batchIntervalExceeded() {
123
+ //if time since last commit > batchCommitInterval
124
+ const lastTime = await this.db.getLastBatchCommitTime();
125
+ return Date.now() - lastTime.getSeconds() > this.batchCommitConfig.interval;
126
+ }
127
+ async getCommitments() {
128
+ // get commitments that have already been used to generate a solution
129
+ return await this.db.getProcessedDappUserCommitments();
130
+ }
131
+ async removeCommitmentsAndSolutions(commitmentIds) {
132
+ const removeSolutionsResult = await this.db.removeProcessedDappUserSolutions(commitmentIds);
133
+ const removeCommitmentsResult = await this.db.removeProcessedDappUserCommitments(commitmentIds);
134
+ this.logger.info('Deleted user solutions', removeSolutionsResult);
135
+ this.logger.info('Deleted user commitments', removeCommitmentsResult);
136
+ }
137
+ convertCommit(commitment) {
138
+ const { processed, userSignature, requestedAt, completedAt, ...commit } = commitment;
139
+ return {
140
+ ...commit,
141
+ userSignaturePart1: userSignature.slice(0, userSignature.length / 2),
142
+ userSignaturePart2: userSignature.slice(userSignature.length / 2),
143
+ // to satisfy typescript
144
+ requestedAt: new util_1.BN(requestedAt).toNumber(),
145
+ completedAt: new util_1.BN(completedAt).toNumber(),
146
+ };
147
+ }
148
+ }
149
+ exports.BatchCommitments = BatchCommitments;
150
+ //# sourceMappingURL=commitments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commitments.js","sourceRoot":"","sources":["../../src/batch/commitments.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from './commitments';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/batch/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./commitments"), exports);
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/batch/index.ts"],"names":[],"mappings":";;;AAAA,wDAA6B"}
@@ -0,0 +1,5 @@
1
+ export * from './tasks';
2
+ export * from './util';
3
+ export * from './batch';
4
+ export * from './api';
5
+ //# sourceMappingURL=index.d.ts.map