@blocklet/meta 1.8.34 → 1.8.35
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/lib/channel.d.ts +27 -0
- package/lib/channel.js +32 -32
- package/lib/constants.d.ts +2 -0
- package/lib/constants.js +6 -3
- package/lib/did.d.ts +10 -0
- package/lib/did.js +18 -24
- package/lib/engine.d.ts +7 -0
- package/lib/engine.js +21 -25
- package/lib/entry.d.ts +3 -0
- package/lib/entry.js +51 -64
- package/lib/extension.d.ts +10 -0
- package/lib/extension.js +78 -77
- package/lib/file.d.ts +21 -0
- package/lib/file.js +44 -39
- package/lib/fix.d.ts +33 -0
- package/lib/fix.js +218 -208
- package/lib/get-component-process-id.d.ts +5 -0
- package/lib/get-component-process-id.js +13 -14
- package/lib/has-reserved-key.d.ts +3 -0
- package/lib/has-reserved-key.js +10 -9
- package/lib/index.d.ts +82 -0
- package/lib/index.js +51 -34
- package/lib/info.d.ts +13 -0
- package/lib/info.js +58 -60
- package/lib/name.d.ts +5 -0
- package/lib/name.js +14 -7
- package/lib/nft-templates.d.ts +86 -0
- package/lib/nft-templates.js +47 -42
- package/lib/parse-navigation.d.ts +3 -0
- package/lib/parse-navigation.js +167 -228
- package/lib/parse.d.ts +22 -0
- package/lib/parse.js +71 -82
- package/lib/payment/index.d.ts +254 -0
- package/lib/payment/index.js +13 -6
- package/lib/payment/v1.d.ts +185 -0
- package/lib/payment/v1.js +80 -81
- package/lib/payment/v2.d.ts +242 -0
- package/lib/payment/v2.js +453 -531
- package/lib/schema.d.ts +50 -0
- package/lib/schema.js +405 -402
- package/lib/service-configs/auth.json +61 -61
- package/lib/service.d.ts +26 -0
- package/lib/service.js +69 -85
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +18 -0
- package/lib/types/schema.d.ts +241 -0
- package/lib/types/schema.js +3 -0
- package/lib/util-meta.d.ts +42 -0
- package/lib/util-meta.js +138 -158
- package/lib/util.d.ts +185 -0
- package/lib/util.js +359 -414
- package/lib/validate.d.ts +10 -0
- package/lib/validate.js +28 -34
- package/lib/verify-multi-sig.d.ts +3 -0
- package/lib/verify-multi-sig.js +94 -101
- package/lib/wallet.d.ts +9 -0
- package/lib/wallet.js +17 -27
- package/package.json +40 -18
package/lib/payment/v2.js
CHANGED
|
@@ -1,48 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
exports.version = exports.checkFreeBlocklet = exports.verifyNftFactory = exports.verifyPaymentIntegrity = exports.createNftFactoryItx = exports._test = void 0;
|
|
1
39
|
/* eslint-disable no-await-in-loop */
|
|
2
|
-
const
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
|
|
40
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
41
|
+
const debug_1 = __importDefault(require("debug"));
|
|
42
|
+
const url_join_1 = __importDefault(require("url-join"));
|
|
43
|
+
const json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
|
|
44
|
+
const get_1 = __importDefault(require("lodash/get"));
|
|
45
|
+
const pick_1 = __importDefault(require("lodash/pick"));
|
|
46
|
+
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
|
|
47
|
+
const axios_1 = __importDefault(require("@abtnode/util/lib/axios"));
|
|
48
|
+
const util_1 = require("@ocap/util");
|
|
49
|
+
const asset_1 = require("@ocap/asset");
|
|
50
|
+
const wallet_1 = require("@ocap/wallet");
|
|
51
|
+
const did_util_1 = require("@arcblock/did-util");
|
|
52
|
+
const did = __importStar(require("@arcblock/did"));
|
|
53
|
+
const constant_1 = __importDefault(require("@abtnode/constant"));
|
|
54
|
+
const nft_templates_1 = require("../nft-templates");
|
|
55
|
+
const validate_1 = require("../validate");
|
|
56
|
+
const util_2 = require("../util");
|
|
57
|
+
const util_meta_1 = require("../util-meta");
|
|
58
|
+
const debug = (0, debug_1.default)('@blocklet/meta:payment');
|
|
59
|
+
const { toTypeInfo } = did;
|
|
60
|
+
const { BLOCKLET_STORE_META_PATH } = constant_1.default;
|
|
21
61
|
const VERSION = '2.0.0';
|
|
22
|
-
|
|
23
|
-
const ZeroBN = new BN(0);
|
|
62
|
+
exports.version = VERSION;
|
|
63
|
+
const ZeroBN = new util_1.BN(0);
|
|
24
64
|
const defaultDecimals = 1e6; // we only support 6 decimals on share ratio
|
|
25
|
-
const defaultDecimalsBN = new BN(defaultDecimals);
|
|
26
|
-
|
|
65
|
+
const defaultDecimalsBN = new util_1.BN(defaultDecimals);
|
|
27
66
|
const getComponentConfig = (meta) => meta.components || meta.children;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const md5 = (str) => crypto.createHash('md5').update(str).digest('hex');
|
|
39
|
-
|
|
40
|
-
const getStoreInfo = async (url) => {
|
|
41
|
-
const storeMetaUrl = joinURL(new URL(url).origin, BLOCKLET_STORE_META_PATH);
|
|
42
|
-
const { data: info } = await axios.get(storeMetaUrl, { timeout: 8000 });
|
|
43
|
-
return info;
|
|
44
|
-
};
|
|
45
|
-
|
|
67
|
+
const safeMul = (a, b) => Number((0, util_1.fromUnitToToken)((0, util_1.fromTokenToUnit)(a)
|
|
68
|
+
.mul(new util_1.BN(b * defaultDecimals))
|
|
69
|
+
.div(defaultDecimalsBN)));
|
|
70
|
+
const md5 = (str) => crypto_1.default.createHash('md5').update(str).digest('hex');
|
|
71
|
+
const getStoreInfo = (url) => __awaiter(void 0, void 0, void 0, function* () {
|
|
72
|
+
const storeMetaUrl = (0, url_join_1.default)(new URL(url).origin, BLOCKLET_STORE_META_PATH);
|
|
73
|
+
const { data: info } = yield axios_1.default.get(storeMetaUrl, { timeout: 8000 });
|
|
74
|
+
return info;
|
|
75
|
+
});
|
|
46
76
|
/**
|
|
47
77
|
* @typedef {{
|
|
48
78
|
* meta: Object
|
|
@@ -51,9 +81,9 @@ const getStoreInfo = async (url) => {
|
|
|
51
81
|
* children: Array<Component>
|
|
52
82
|
* }} Component
|
|
53
83
|
*
|
|
54
|
-
* @param {
|
|
84
|
+
* @param {TBlockletMeta} inputMeta
|
|
55
85
|
* @param {{
|
|
56
|
-
* ancestors: Array<{
|
|
86
|
+
* ancestors: Array<{TBlockletMeta}>
|
|
57
87
|
* bundles: {
|
|
58
88
|
* <bundleName>: <storeId>
|
|
59
89
|
* }
|
|
@@ -61,164 +91,135 @@ const getStoreInfo = async (url) => {
|
|
|
61
91
|
*
|
|
62
92
|
* @returns {Array<Component>}
|
|
63
93
|
*/
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
throw new Error('The depth of component should not exceed 40');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const configs = getComponentConfig(inputMeta);
|
|
74
|
-
|
|
75
|
-
if (!configs || !configs.length) {
|
|
76
|
-
return [];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const children = [];
|
|
80
|
-
|
|
81
|
-
for (const config of configs) {
|
|
82
|
-
// get component meta
|
|
83
|
-
const urls = getSourceUrlsFromConfig(config);
|
|
84
|
-
let meta;
|
|
85
|
-
let url;
|
|
86
|
-
try {
|
|
87
|
-
const res = await getBlockletMetaFromUrls(urls, {
|
|
88
|
-
returnUrl: true,
|
|
89
|
-
validateFn: (m) => validateMeta(m),
|
|
90
|
-
ensureTarball: false,
|
|
91
|
-
});
|
|
92
|
-
meta = res.meta;
|
|
93
|
-
url = res.url;
|
|
94
|
-
} catch (err) {
|
|
95
|
-
throw new Error(`Failed get component meta: ${config.title || config.name}: ${err.message}`);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// check is component
|
|
99
|
-
if (!isComponentBlocklet(meta)) {
|
|
100
|
-
throw new Error(`The blocklet cannot be a component: ${meta.title}`);
|
|
94
|
+
const innerGetComponents = (inputMeta, context = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
// FIXME 是否需要验证: 在同一个链上; 重复的 component
|
|
96
|
+
const { ancestors = [], bundles = {} } = context;
|
|
97
|
+
// check ancestor length
|
|
98
|
+
if (ancestors.length > 40) {
|
|
99
|
+
throw new Error('The depth of component should not exceed 40');
|
|
101
100
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
throw new Error('Blocklet components have circular dependencies');
|
|
101
|
+
const configs = getComponentConfig(inputMeta);
|
|
102
|
+
if (!configs || !configs.length) {
|
|
103
|
+
return [];
|
|
106
104
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
105
|
+
const children = [];
|
|
106
|
+
for (const config of configs) {
|
|
107
|
+
// get component meta
|
|
108
|
+
const urls = (0, util_meta_1.getSourceUrlsFromConfig)(config);
|
|
109
|
+
let meta;
|
|
110
|
+
let url;
|
|
111
|
+
try {
|
|
112
|
+
const res = yield (0, util_meta_1.getBlockletMetaFromUrls)(urls, {
|
|
113
|
+
returnUrl: true,
|
|
114
|
+
validateFn: (m) => (0, validate_1.validateMeta)(m),
|
|
115
|
+
ensureTarball: false,
|
|
116
|
+
});
|
|
117
|
+
meta = res.meta;
|
|
118
|
+
url = res.url;
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
throw new Error(`Failed get component meta: ${config.title || config.name}: ${err.message}`);
|
|
122
|
+
}
|
|
123
|
+
// check is component
|
|
124
|
+
if (!(0, util_2.isComponentBlocklet)(meta)) {
|
|
125
|
+
throw new Error(`The blocklet cannot be a component: ${meta.title}`);
|
|
126
|
+
}
|
|
127
|
+
// check circular dependencies
|
|
128
|
+
if (ancestors.map((x) => { var _a; return (_a = x.meta) === null || _a === void 0 ? void 0 : _a.did; }).indexOf(meta.did) > -1) {
|
|
129
|
+
throw new Error('Blocklet components have circular dependencies');
|
|
130
|
+
}
|
|
131
|
+
// generate child
|
|
132
|
+
const child = {
|
|
133
|
+
meta,
|
|
134
|
+
};
|
|
135
|
+
// child store info
|
|
136
|
+
if (config.source.store) {
|
|
137
|
+
const storeInfo = yield getStoreInfo(url);
|
|
138
|
+
// check uniq bundle did in different stores
|
|
139
|
+
if (!bundles[child.meta.did]) {
|
|
140
|
+
bundles[child.meta.did] = storeInfo.id;
|
|
141
|
+
}
|
|
142
|
+
else if (bundles[child.meta.did] !== storeInfo.id) {
|
|
143
|
+
throw new Error('Bundles with the same did cannot in different stores');
|
|
144
|
+
}
|
|
145
|
+
child.storeInfo = storeInfo;
|
|
146
|
+
child.storeUrl = new URL(url).origin;
|
|
147
|
+
}
|
|
148
|
+
// child children
|
|
149
|
+
child.children = yield innerGetComponents(meta, {
|
|
150
|
+
ancestors: [...ancestors, { meta }],
|
|
151
|
+
bundles,
|
|
152
|
+
});
|
|
153
|
+
children.push(child);
|
|
126
154
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
child.children = await _getComponents(meta, {
|
|
130
|
-
ancestors: [...ancestors, { meta }],
|
|
131
|
-
bundles,
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
children.push(child);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
return children;
|
|
138
|
-
};
|
|
139
|
-
|
|
155
|
+
return children;
|
|
156
|
+
});
|
|
140
157
|
/**
|
|
141
|
-
* @typedef {{
|
|
142
|
-
* id: string
|
|
143
|
-
* pk: string
|
|
144
|
-
* url: string
|
|
145
|
-
* components: Array<{did: string, version: string}>
|
|
146
|
-
* }} Store
|
|
147
158
|
* @param {Array<Component>} components
|
|
148
159
|
* @param {Array<Store>} _stores
|
|
149
160
|
* @returns {Array<Store>}
|
|
150
161
|
*/
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
162
|
+
const getStores = (components, _stores = []) => {
|
|
163
|
+
for (const { meta, storeInfo, storeUrl, children } of components) {
|
|
164
|
+
if (storeInfo && (!(0, util_2.isFreeBlocklet)(meta) || !(0, util_2.isFreeComponent)(meta))) {
|
|
165
|
+
const store = _stores.find((x) => x.id === storeInfo.id);
|
|
166
|
+
if (!store) {
|
|
167
|
+
_stores.push({
|
|
168
|
+
id: storeInfo.id,
|
|
169
|
+
pk: storeInfo.pk,
|
|
170
|
+
url: storeUrl,
|
|
171
|
+
components: [{ did: meta.did, version: meta.version }],
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
else if (!store.components.some((x) => x.did === meta.did && x.version === meta.version)) {
|
|
175
|
+
store.components.push({ did: meta.did, version: meta.version });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (children && children.length > 0) {
|
|
179
|
+
getStores(children, _stores);
|
|
180
|
+
}
|
|
165
181
|
}
|
|
166
|
-
|
|
167
|
-
if (children && children.length > 0) {
|
|
168
|
-
_getStores(children, _stores);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return _stores;
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const getComponents = async (inputMeta) => {
|
|
176
|
-
const components = await _getComponents(inputMeta);
|
|
177
|
-
const stores = await _getStores(components);
|
|
178
|
-
return { components, stores };
|
|
182
|
+
return _stores;
|
|
179
183
|
};
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
184
|
+
const getComponents = (inputMeta) => __awaiter(void 0, void 0, void 0, function* () {
|
|
185
|
+
const components = yield innerGetComponents(inputMeta);
|
|
186
|
+
const stores = yield getStores(components);
|
|
187
|
+
return { components, stores };
|
|
188
|
+
});
|
|
189
|
+
const getPriceTokens = (meta, ocapClient) => __awaiter(void 0, void 0, void 0, function* () {
|
|
190
|
+
const priceTokens = (0, cloneDeep_1.default)((0, get_1.default)(meta, 'payment.price', []));
|
|
191
|
+
for (const token of priceTokens) {
|
|
192
|
+
// eslint-disable-next-line no-await-in-loop
|
|
193
|
+
const { state } = yield ocapClient.getTokenState({ address: token.address });
|
|
194
|
+
if (!state) {
|
|
195
|
+
throw new Error(`Token specified in blocklet meta was not found on chain: ${token.address}`);
|
|
196
|
+
}
|
|
197
|
+
token.decimal = state.decimal;
|
|
188
198
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
return priceTokens;
|
|
193
|
-
};
|
|
194
|
-
|
|
199
|
+
return priceTokens;
|
|
200
|
+
});
|
|
195
201
|
const getChildShare = (childMeta, parentPrice) => {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
price = safeMul(parentPrice, value);
|
|
215
|
-
}
|
|
202
|
+
var _a;
|
|
203
|
+
if (!((_a = childMeta === null || childMeta === void 0 ? void 0 : childMeta.payment) === null || _a === void 0 ? void 0 : _a.componentPrice)) {
|
|
204
|
+
return 0;
|
|
205
|
+
}
|
|
206
|
+
const priceList = childMeta.payment.componentPrice;
|
|
207
|
+
let price = 0;
|
|
208
|
+
for (const { type, value, parentPriceRange } of priceList) {
|
|
209
|
+
const isDefault = !parentPriceRange || !parentPriceRange.length;
|
|
210
|
+
const skip = isDefault && price !== 0;
|
|
211
|
+
const inRange = isDefault || (parentPriceRange && parentPrice >= parentPriceRange[0] && parentPrice <= parentPriceRange[1]);
|
|
212
|
+
if (!skip && inRange) {
|
|
213
|
+
if (type === 'fixed') {
|
|
214
|
+
price = value;
|
|
215
|
+
}
|
|
216
|
+
else if (type === 'percentage') {
|
|
217
|
+
price = safeMul(parentPrice, value);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
216
220
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
return price;
|
|
221
|
+
return price;
|
|
220
222
|
};
|
|
221
|
-
|
|
222
223
|
/**
|
|
223
224
|
* @returns {Array<{
|
|
224
225
|
* tokenAddress: string
|
|
@@ -226,99 +227,69 @@ const getChildShare = (childMeta, parentPrice) => {
|
|
|
226
227
|
* amount: BN
|
|
227
228
|
* }>}
|
|
228
229
|
*/
|
|
229
|
-
const getTokenTransfers = ({ priceToken, shares = [], components = [] }) => {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const { value: price } = priceToken;
|
|
237
|
-
|
|
238
|
-
let parentShareBN = fromTokenToUnit(price, priceToken.decimal);
|
|
239
|
-
|
|
240
|
-
const contracts = [];
|
|
241
|
-
|
|
242
|
-
for (const child of components) {
|
|
243
|
-
if (!isFreeComponent(child.meta)) {
|
|
244
|
-
// // check same token
|
|
245
|
-
const [token] = child.meta.payment.price || [];
|
|
246
|
-
if (token && token.address !== priceToken.address) {
|
|
247
|
-
throw new Error(
|
|
248
|
-
`The token address of the component "${
|
|
249
|
-
child.meta.title || child.meta.name
|
|
250
|
-
}" is inconsistent with the blocklet. Component: ${priceToken.address}, Composite Blocklet: ${token.address}`
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const childShare = getChildShare(child.meta, price);
|
|
255
|
-
|
|
256
|
-
parentShareBN = parentShareBN.sub(fromTokenToUnit(childShare, priceToken.decimal));
|
|
257
|
-
|
|
258
|
-
const componentContracts = getTokenTransfers({
|
|
259
|
-
priceToken: { ...priceToken, value: childShare },
|
|
260
|
-
shares: child.meta.payment.share,
|
|
261
|
-
components: child.children || [],
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
contracts.push(...componentContracts);
|
|
230
|
+
const getTokenTransfers = ({ priceToken, shares = [], components = [], }) => {
|
|
231
|
+
// check share
|
|
232
|
+
const shareSum = shares.reduce((sum, x) => sum + x.value, 0);
|
|
233
|
+
if (shareSum > 1) {
|
|
234
|
+
throw new Error('payment.share invalid: share sum should not be greater than 1');
|
|
265
235
|
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
contracts.forEach((x) => {
|
|
287
|
-
const index = mergedContracts.findIndex(
|
|
288
|
-
(y) => y.tokenAddress === x.tokenAddress && y.accountAddress === x.accountAddress
|
|
289
|
-
);
|
|
290
|
-
if (index > -1) {
|
|
291
|
-
mergedContracts[index].amount = mergedContracts[index].amount.add(x.amount);
|
|
292
|
-
} else {
|
|
293
|
-
mergedContracts.push(x);
|
|
236
|
+
const { value: price } = priceToken;
|
|
237
|
+
let parentShareBN = (0, util_1.fromTokenToUnit)(price, priceToken.decimal);
|
|
238
|
+
const contracts = [];
|
|
239
|
+
for (const child of components) {
|
|
240
|
+
if (!(0, util_2.isFreeComponent)(child.meta)) {
|
|
241
|
+
// // check same token
|
|
242
|
+
const [token] = child.meta.payment.price || [];
|
|
243
|
+
if (token && token.address !== priceToken.address) {
|
|
244
|
+
throw new Error(`The token address of the component "${child.meta.title || child.meta.name}" is inconsistent with the blocklet. Component: ${priceToken.address}, Composite Blocklet: ${token.address}`);
|
|
245
|
+
}
|
|
246
|
+
const childShare = getChildShare(child.meta, price);
|
|
247
|
+
parentShareBN = parentShareBN.sub((0, util_1.fromTokenToUnit)(childShare, priceToken.decimal));
|
|
248
|
+
const componentContracts = getTokenTransfers({
|
|
249
|
+
priceToken: Object.assign(Object.assign({}, priceToken), { value: childShare }),
|
|
250
|
+
shares: child.meta.payment.share,
|
|
251
|
+
components: child.children || [],
|
|
252
|
+
});
|
|
253
|
+
contracts.push(...componentContracts);
|
|
254
|
+
}
|
|
294
255
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
.
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
shares: shareList,
|
|
319
|
-
};
|
|
256
|
+
if (parentShareBN.lt(ZeroBN)) {
|
|
257
|
+
const needPrice = (0, util_1.fromUnitToToken)((0, util_1.fromTokenToUnit)(price, priceToken.decimal).sub(parentShareBN));
|
|
258
|
+
throw new Error(`Price for composite blocklet must be greater than ${needPrice} because paid components are included.`);
|
|
259
|
+
}
|
|
260
|
+
shares.forEach(({ name, address: accountAddress, value: ratio }) => {
|
|
261
|
+
contracts.push({
|
|
262
|
+
tokenAddress: priceToken.address,
|
|
263
|
+
accountName: name,
|
|
264
|
+
accountAddress,
|
|
265
|
+
amount: parentShareBN.mul(new util_1.BN(ratio * defaultDecimals)).div(defaultDecimalsBN),
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
const mergedContracts = [];
|
|
269
|
+
contracts.forEach((x) => {
|
|
270
|
+
const index = mergedContracts.findIndex((y) => y.tokenAddress === x.tokenAddress && y.accountAddress === x.accountAddress);
|
|
271
|
+
if (index > -1) {
|
|
272
|
+
mergedContracts[index].amount = mergedContracts[index].amount.add(x.amount);
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
mergedContracts.push(x);
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
return mergedContracts;
|
|
320
279
|
};
|
|
321
|
-
|
|
280
|
+
const getContract = ({ meta, priceTokens, components, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
281
|
+
const shares = meta.payment.share || [];
|
|
282
|
+
const [priceToken] = priceTokens;
|
|
283
|
+
const contracts = getTokenTransfers({ priceToken, shares, components });
|
|
284
|
+
const code = contracts
|
|
285
|
+
.map((x) => `transferToken('${x.tokenAddress}','${x.accountAddress}','${x.amount.toString()}')`)
|
|
286
|
+
.join(';\n');
|
|
287
|
+
const shareList = contracts.map((x) => (Object.assign(Object.assign({}, x), { amount: (0, util_1.fromUnitToToken)(x.amount, priceToken.decimal) })));
|
|
288
|
+
return {
|
|
289
|
+
code,
|
|
290
|
+
shares: shareList,
|
|
291
|
+
};
|
|
292
|
+
});
|
|
322
293
|
/**
|
|
323
294
|
* we need to ensure that blocklet purchase factory does not change across changes
|
|
324
295
|
*
|
|
@@ -345,151 +316,130 @@ const getContract = async ({ meta, priceTokens, components }) => {
|
|
|
345
316
|
* }} Itx
|
|
346
317
|
* @returns {Itx}
|
|
347
318
|
*/
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
319
|
+
const innerCreateNftFactoryItx = ({ meta, issuers, serviceUrl, storeSignatures, factoryInput, contract, }) => {
|
|
320
|
+
const factoryOutput = (0, nft_templates_1.getBlockletPurchaseTemplate)(serviceUrl);
|
|
321
|
+
const itx = {
|
|
322
|
+
name: meta.title || meta.name,
|
|
323
|
+
description: `Purchase NFT factory for blocklet ${meta.name}`,
|
|
324
|
+
settlement: 'instant',
|
|
325
|
+
limit: 0,
|
|
326
|
+
trustedIssuers: issuers,
|
|
327
|
+
input: factoryInput,
|
|
328
|
+
output: {
|
|
329
|
+
issuer: '{{ctx.issuer.id}}',
|
|
330
|
+
parent: '{{ctx.factory}}',
|
|
331
|
+
moniker: 'BlockletPurchaseNFT',
|
|
332
|
+
readonly: true,
|
|
333
|
+
transferrable: false,
|
|
334
|
+
data: factoryOutput,
|
|
335
|
+
},
|
|
336
|
+
data: {
|
|
337
|
+
type: 'json',
|
|
338
|
+
value: {
|
|
339
|
+
did: meta.did,
|
|
340
|
+
url: (0, url_join_1.default)(serviceUrl, `/blocklet/${meta.did}`),
|
|
341
|
+
name: meta.name,
|
|
342
|
+
version: meta.version,
|
|
343
|
+
payment: {
|
|
344
|
+
version: VERSION,
|
|
345
|
+
},
|
|
346
|
+
stores: storeSignatures.map((x) => (0, pick_1.default)(x, ['signer', 'pk', 'signature', 'components', 'paymentIntegrity'])),
|
|
347
|
+
},
|
|
374
348
|
},
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
itx.address = toFactoryAddress(itx);
|
|
388
|
-
|
|
389
|
-
isValidFactory(itx, true);
|
|
390
|
-
|
|
391
|
-
return itx;
|
|
349
|
+
hooks: [
|
|
350
|
+
{
|
|
351
|
+
name: 'mint',
|
|
352
|
+
type: 'contract',
|
|
353
|
+
hook: contract,
|
|
354
|
+
},
|
|
355
|
+
],
|
|
356
|
+
};
|
|
357
|
+
itx.address = (0, did_util_1.toFactoryAddress)(itx);
|
|
358
|
+
// @ts-expect-error FIXME: help wanted
|
|
359
|
+
(0, asset_1.isValidFactory)(itx, true);
|
|
360
|
+
return itx;
|
|
392
361
|
};
|
|
393
|
-
|
|
394
362
|
const getFactoryInput = (inputTokens, { formatToken = true } = {}) => {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
};
|
|
408
|
-
|
|
409
|
-
const getPaymentIntegrity = async ({ contract, factoryInput, storeComponents, meta, client, storeId }) => {
|
|
410
|
-
if (!contract && !factoryInput && !storeComponents) {
|
|
411
|
-
const priceTokens = await getPriceTokens(meta, client);
|
|
412
|
-
const { components, stores } = await getComponents(meta);
|
|
413
|
-
const store = stores.find((x) => x.id === storeId);
|
|
414
|
-
|
|
415
|
-
// eslint-disable-next-line no-param-reassign
|
|
416
|
-
contract = (await getContract({ meta, components, priceTokens })).code;
|
|
417
|
-
// eslint-disable-next-line no-param-reassign
|
|
418
|
-
factoryInput = await getFactoryInput(priceTokens);
|
|
419
|
-
// eslint-disable-next-line no-param-reassign
|
|
420
|
-
storeComponents = store?.components || [];
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
const paymentData = {
|
|
424
|
-
factoryInput,
|
|
425
|
-
contract,
|
|
426
|
-
components: storeComponents || [],
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
const integrity = md5(stableStringify(paymentData));
|
|
430
|
-
|
|
431
|
-
return integrity;
|
|
363
|
+
const tokens = (0, cloneDeep_1.default)(inputTokens);
|
|
364
|
+
tokens.forEach((token) => {
|
|
365
|
+
if (formatToken) {
|
|
366
|
+
token.value = (0, util_1.fromTokenToUnit)(token.value, token.decimal).toString();
|
|
367
|
+
}
|
|
368
|
+
delete token.decimal;
|
|
369
|
+
});
|
|
370
|
+
return {
|
|
371
|
+
tokens,
|
|
372
|
+
assets: [],
|
|
373
|
+
variables: [],
|
|
374
|
+
};
|
|
432
375
|
};
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
* body: { blockletMeta, paymentIntegrity, paymentVersion }
|
|
445
|
-
* return: { signer, pk, signature}
|
|
446
|
-
*/
|
|
447
|
-
const { data: res } = await axios.post(
|
|
448
|
-
`${url}/api/payment/signature`,
|
|
449
|
-
{
|
|
450
|
-
blockletMeta: meta,
|
|
451
|
-
paymentIntegrity,
|
|
452
|
-
paymentVersion: VERSION,
|
|
453
|
-
},
|
|
454
|
-
{ timeout: 20000 }
|
|
455
|
-
);
|
|
456
|
-
|
|
457
|
-
if (res.signer !== id) {
|
|
458
|
-
throw new Error('store signature: store id does not match');
|
|
376
|
+
const getPaymentIntegrity = ({ contract, factoryInput, storeComponents, meta, client, storeId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
377
|
+
if (!contract && !factoryInput && !storeComponents) {
|
|
378
|
+
const priceTokens = yield getPriceTokens(meta, client);
|
|
379
|
+
const { components, stores } = yield getComponents(meta);
|
|
380
|
+
const store = stores.find((x) => x.id === storeId);
|
|
381
|
+
// eslint-disable-next-line no-param-reassign
|
|
382
|
+
contract = (yield getContract({ meta, components, priceTokens })).code;
|
|
383
|
+
// eslint-disable-next-line no-param-reassign
|
|
384
|
+
factoryInput = yield getFactoryInput(priceTokens);
|
|
385
|
+
// eslint-disable-next-line no-param-reassign
|
|
386
|
+
storeComponents = (store === null || store === void 0 ? void 0 : store.components) || [];
|
|
459
387
|
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
388
|
+
const paymentData = {
|
|
389
|
+
factoryInput,
|
|
390
|
+
contract,
|
|
391
|
+
components: storeComponents || [],
|
|
392
|
+
};
|
|
393
|
+
const integrity = md5((0, json_stable_stringify_1.default)(paymentData));
|
|
394
|
+
return integrity;
|
|
395
|
+
});
|
|
396
|
+
const getStoreSignatures = ({ meta, stores, factoryInput, contract, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
397
|
+
const storeSignatures = [];
|
|
398
|
+
for (const store of stores) {
|
|
399
|
+
const { id, url, pk, components: storeComponents } = store;
|
|
400
|
+
const paymentIntegrity = yield getPaymentIntegrity({ factoryInput, contract, storeComponents });
|
|
401
|
+
/**
|
|
402
|
+
* protocol: /api/payment/signature
|
|
403
|
+
* method: POST
|
|
404
|
+
* body: { blockletMeta, paymentIntegrity, paymentVersion }
|
|
405
|
+
* return: { signer, pk, signature}
|
|
406
|
+
*/
|
|
407
|
+
const { data: res } = yield axios_1.default.post(`${url}/api/payment/signature`, {
|
|
408
|
+
blockletMeta: meta,
|
|
409
|
+
paymentIntegrity,
|
|
410
|
+
paymentVersion: VERSION,
|
|
411
|
+
}, { timeout: 20000 });
|
|
412
|
+
if (res.signer !== id) {
|
|
413
|
+
throw new Error('store signature: store id does not match');
|
|
414
|
+
}
|
|
415
|
+
if (res.pk !== pk) {
|
|
416
|
+
throw new Error('store signature: store pk does not match');
|
|
417
|
+
}
|
|
418
|
+
// verify sig
|
|
419
|
+
const type = toTypeInfo(id);
|
|
420
|
+
const wallet = (0, wallet_1.fromPublicKey)(pk, type);
|
|
421
|
+
const verifyRes = wallet.verify(paymentIntegrity, res.signature);
|
|
422
|
+
if (verifyRes !== true) {
|
|
423
|
+
throw new Error('verify store signature failed');
|
|
424
|
+
}
|
|
425
|
+
storeSignatures.push({
|
|
426
|
+
signer: res.signer,
|
|
427
|
+
pk: res.pk,
|
|
428
|
+
signature: res.signature,
|
|
429
|
+
components: storeComponents,
|
|
430
|
+
paymentIntegrity,
|
|
431
|
+
storeUrl: url,
|
|
432
|
+
});
|
|
471
433
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
signature: res.signature,
|
|
477
|
-
components: storeComponents,
|
|
478
|
-
paymentIntegrity,
|
|
479
|
-
storeUrl: url,
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
return {
|
|
484
|
-
storeSignatures,
|
|
485
|
-
};
|
|
486
|
-
};
|
|
487
|
-
|
|
434
|
+
return {
|
|
435
|
+
storeSignatures,
|
|
436
|
+
};
|
|
437
|
+
});
|
|
488
438
|
/**
|
|
489
439
|
* Used by CLI and Store to independent compute factory itx
|
|
490
440
|
*
|
|
491
441
|
* @param {{
|
|
492
|
-
* blockletMeta:
|
|
442
|
+
* blockletMeta: TBlockletMeta,
|
|
493
443
|
* ocapClient: OcapClient,
|
|
494
444
|
* issuers: Array<string>,
|
|
495
445
|
* storeUrl: string,
|
|
@@ -505,66 +455,54 @@ const getStoreSignatures = async ({ meta, stores, factoryInput, contract }) => {
|
|
|
505
455
|
* }>
|
|
506
456
|
* }}
|
|
507
457
|
*/
|
|
508
|
-
const createNftFactoryItx =
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
stores,
|
|
538
|
-
storeSignatures,
|
|
539
|
-
factoryInput,
|
|
540
|
-
contract,
|
|
541
|
-
}),
|
|
542
|
-
stores: storeSignatures.map((x) => ({ id: x.signer, url: x.storeUrl })),
|
|
543
|
-
shares,
|
|
544
|
-
};
|
|
545
|
-
};
|
|
546
|
-
|
|
458
|
+
const createNftFactoryItx = ({ blockletMeta, ocapClient, issuers, storeUrl, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
459
|
+
const priceTokens = yield getPriceTokens(blockletMeta, ocapClient);
|
|
460
|
+
const { components, stores } = yield getComponents(blockletMeta);
|
|
461
|
+
const factoryInput = getFactoryInput(priceTokens);
|
|
462
|
+
const { code: contract, shares } = yield getContract({
|
|
463
|
+
meta: blockletMeta,
|
|
464
|
+
priceTokens,
|
|
465
|
+
components,
|
|
466
|
+
});
|
|
467
|
+
const { storeSignatures } = yield getStoreSignatures({
|
|
468
|
+
meta: blockletMeta,
|
|
469
|
+
stores,
|
|
470
|
+
factoryInput,
|
|
471
|
+
contract,
|
|
472
|
+
});
|
|
473
|
+
return {
|
|
474
|
+
itx: innerCreateNftFactoryItx({
|
|
475
|
+
meta: blockletMeta,
|
|
476
|
+
issuers,
|
|
477
|
+
serviceUrl: storeUrl,
|
|
478
|
+
storeSignatures,
|
|
479
|
+
factoryInput,
|
|
480
|
+
contract,
|
|
481
|
+
}),
|
|
482
|
+
stores: storeSignatures.map((x) => ({ id: x.signer, url: x.storeUrl })),
|
|
483
|
+
shares,
|
|
484
|
+
};
|
|
485
|
+
});
|
|
486
|
+
exports.createNftFactoryItx = createNftFactoryItx;
|
|
547
487
|
/**
|
|
548
488
|
* Used by Store before generating payment signature
|
|
549
489
|
*
|
|
550
490
|
* @param {{
|
|
551
491
|
* integrity: string,
|
|
552
|
-
* blockletMeta:
|
|
492
|
+
* blockletMeta: TBlockletMeta,
|
|
553
493
|
* ocapClient: OcapClient,
|
|
554
494
|
* storeId: string
|
|
555
495
|
* }}
|
|
556
496
|
* @returns {string} integrity
|
|
557
497
|
*/
|
|
558
|
-
const verifyPaymentIntegrity =
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
};
|
|
567
|
-
|
|
498
|
+
const verifyPaymentIntegrity = ({ integrity: expected, blockletMeta, ocapClient, storeId, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
499
|
+
const actual = yield getPaymentIntegrity({ meta: blockletMeta, client: ocapClient, storeId });
|
|
500
|
+
if (actual !== expected) {
|
|
501
|
+
throw new Error('verify payment integrity failed');
|
|
502
|
+
}
|
|
503
|
+
return expected;
|
|
504
|
+
});
|
|
505
|
+
exports.verifyPaymentIntegrity = verifyPaymentIntegrity;
|
|
568
506
|
/**
|
|
569
507
|
* Used by Store before generating downloadToken
|
|
570
508
|
*
|
|
@@ -577,83 +515,67 @@ const verifyPaymentIntegrity = async ({ integrity: expected, blockletMeta, ocapC
|
|
|
577
515
|
* components: Array<{did: string, version: string}>
|
|
578
516
|
* }}
|
|
579
517
|
*/
|
|
580
|
-
const verifyNftFactory =
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
);
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
if (signerWallet.sign(integrity) !== store.signature) {
|
|
607
|
-
debug(store, factoryInput, integrity, components, c.hook);
|
|
608
|
-
throw new Error(`verify nft factory failed: ${factoryState.address}`);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
return { components };
|
|
612
|
-
};
|
|
613
|
-
|
|
518
|
+
const verifyNftFactory = ({ factoryState, signerWallet, }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
519
|
+
var _a;
|
|
520
|
+
const data = JSON.parse((_a = factoryState === null || factoryState === void 0 ? void 0 : factoryState.data) === null || _a === void 0 ? void 0 : _a.value);
|
|
521
|
+
const stores = (data === null || data === void 0 ? void 0 : data.stores) || [];
|
|
522
|
+
const store = stores.find((x) => x.signer === signerWallet.address);
|
|
523
|
+
if (!store) {
|
|
524
|
+
throw new Error(`Signer does not found in factory. factory: ${factoryState.address}, signer: ${signerWallet.address}`);
|
|
525
|
+
}
|
|
526
|
+
const c = factoryState.hooks.find((x) => x.type === 'contract');
|
|
527
|
+
const { components } = store;
|
|
528
|
+
// Token 的字段和 factory 中的字段不一致
|
|
529
|
+
const factoryInput = getFactoryInput(factoryState.input.tokens.map((x) => (0, pick_1.default)(x, ['address', 'value'])), { formatToken: false });
|
|
530
|
+
const integrity = yield getPaymentIntegrity({
|
|
531
|
+
contract: c.hook,
|
|
532
|
+
factoryInput,
|
|
533
|
+
storeComponents: components,
|
|
534
|
+
});
|
|
535
|
+
if (signerWallet.sign(integrity) !== store.signature) {
|
|
536
|
+
debug(store, factoryInput, integrity, components, c.hook);
|
|
537
|
+
throw new Error(`verify nft factory failed: ${factoryState.address}`);
|
|
538
|
+
}
|
|
539
|
+
return { components };
|
|
540
|
+
});
|
|
541
|
+
exports.verifyNftFactory = verifyNftFactory;
|
|
614
542
|
/**
|
|
615
543
|
* Check blocklet and all of components are free
|
|
616
544
|
* Throw Error if not free
|
|
617
545
|
*
|
|
618
|
-
* @param {
|
|
546
|
+
* @param {TBlockletMeta} meta
|
|
619
547
|
*/
|
|
620
|
-
const checkFreeBlocklet =
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
shouldAllComponentFree(components);
|
|
642
|
-
|
|
643
|
-
return true;
|
|
644
|
-
};
|
|
645
|
-
|
|
646
|
-
module.exports = {
|
|
647
|
-
createNftFactoryItx,
|
|
648
|
-
verifyPaymentIntegrity,
|
|
649
|
-
verifyNftFactory,
|
|
650
|
-
checkFreeBlocklet,
|
|
651
|
-
version: VERSION,
|
|
652
|
-
_test: {
|
|
548
|
+
const checkFreeBlocklet = (blockletMeta) => __awaiter(void 0, void 0, void 0, function* () {
|
|
549
|
+
if (!(0, util_2.isFreeBlocklet)(blockletMeta)) {
|
|
550
|
+
return Promise.reject(new Error('blocklet is not free'));
|
|
551
|
+
}
|
|
552
|
+
const { components } = yield getComponents(blockletMeta);
|
|
553
|
+
const shouldAllComponentFree = (arr) => {
|
|
554
|
+
arr.forEach(({ meta, children }) => {
|
|
555
|
+
if (!(0, util_2.isFreeBlocklet)(meta) || !(0, util_2.isFreeComponent)(meta)) {
|
|
556
|
+
// throw new Error(`Found paid component "${meta.title || meta.name}" in free blocklet`);
|
|
557
|
+
throw new Error(`Paid component "${meta.title || meta.name}" found in free blocklet "${blockletMeta.title || blockletMeta.name}", which is forbidden`);
|
|
558
|
+
}
|
|
559
|
+
shouldAllComponentFree(children || []);
|
|
560
|
+
});
|
|
561
|
+
};
|
|
562
|
+
shouldAllComponentFree(components);
|
|
563
|
+
return true;
|
|
564
|
+
});
|
|
565
|
+
exports.checkFreeBlocklet = checkFreeBlocklet;
|
|
566
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
567
|
+
exports._test = {
|
|
653
568
|
getPriceTokens,
|
|
654
569
|
getFactoryInput,
|
|
655
570
|
getPaymentIntegrity,
|
|
656
571
|
getComponents,
|
|
657
572
|
getContract,
|
|
658
|
-
|
|
573
|
+
};
|
|
574
|
+
exports.default = {
|
|
575
|
+
createNftFactoryItx,
|
|
576
|
+
verifyPaymentIntegrity,
|
|
577
|
+
verifyNftFactory,
|
|
578
|
+
checkFreeBlocklet,
|
|
579
|
+
version: VERSION,
|
|
580
|
+
_test: exports._test,
|
|
659
581
|
};
|