@ocap/tx-protocols 1.28.9 → 1.29.0

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.
Files changed (284) hide show
  1. package/esm/execute.d.mts +53 -0
  2. package/esm/execute.mjs +225 -0
  3. package/esm/index.d.mts +95 -0
  4. package/esm/index.mjs +100 -0
  5. package/esm/pipes/ensure-cost.d.mts +18 -0
  6. package/esm/pipes/ensure-cost.mjs +136 -0
  7. package/esm/pipes/ensure-gas.d.mts +14 -0
  8. package/esm/pipes/ensure-gas.mjs +38 -0
  9. package/esm/protocols/account/delegate.d.mts +4 -0
  10. package/esm/protocols/account/delegate.mjs +195 -0
  11. package/esm/protocols/account/migrate.d.mts +4 -0
  12. package/esm/protocols/account/migrate.mjs +130 -0
  13. package/esm/protocols/account/revoke-delegate.d.mts +4 -0
  14. package/esm/protocols/account/revoke-delegate.mjs +102 -0
  15. package/esm/protocols/asset/acquire-v2.d.mts +9 -0
  16. package/esm/protocols/asset/acquire-v2.mjs +213 -0
  17. package/esm/protocols/asset/acquire-v3.d.mts +17 -0
  18. package/esm/protocols/asset/acquire-v3.mjs +265 -0
  19. package/esm/protocols/asset/calls/transfer-token.d.mts +4 -0
  20. package/esm/protocols/asset/calls/transfer-token.mjs +36 -0
  21. package/esm/protocols/asset/calls/transfer.d.mts +4 -0
  22. package/esm/protocols/asset/calls/transfer.mjs +32 -0
  23. package/esm/protocols/asset/consume.d.mts +4 -0
  24. package/esm/protocols/asset/consume.mjs +92 -0
  25. package/esm/protocols/asset/create.d.mts +4 -0
  26. package/esm/protocols/asset/create.mjs +136 -0
  27. package/esm/protocols/asset/mint.d.mts +4 -0
  28. package/esm/protocols/asset/mint.mjs +156 -0
  29. package/esm/protocols/asset/pipes/exec-mint-hook.d.mts +24 -0
  30. package/esm/protocols/asset/pipes/exec-mint-hook.mjs +54 -0
  31. package/esm/protocols/asset/pipes/extract-factory-tokens.d.mts +21 -0
  32. package/esm/protocols/asset/pipes/extract-factory-tokens.mjs +22 -0
  33. package/esm/protocols/asset/pipes/verify-itx-address.d.mts +32 -0
  34. package/esm/protocols/asset/pipes/verify-itx-address.mjs +56 -0
  35. package/esm/protocols/asset/pipes/verify-itx-assets.d.mts +18 -0
  36. package/esm/protocols/asset/pipes/verify-itx-assets.mjs +27 -0
  37. package/esm/protocols/asset/pipes/verify-itx-variables.d.mts +17 -0
  38. package/esm/protocols/asset/pipes/verify-itx-variables.mjs +20 -0
  39. package/esm/protocols/asset/pipes/verify-mint-limit.d.mts +15 -0
  40. package/esm/protocols/asset/pipes/verify-mint-limit.mjs +14 -0
  41. package/esm/protocols/asset/update.d.mts +4 -0
  42. package/esm/protocols/asset/update.mjs +111 -0
  43. package/esm/protocols/factory/create.d.mts +29 -0
  44. package/esm/protocols/factory/create.mjs +155 -0
  45. package/esm/protocols/governance/claim-stake.d.mts +27 -0
  46. package/esm/protocols/governance/claim-stake.mjs +220 -0
  47. package/esm/protocols/governance/return-stake.d.mts +27 -0
  48. package/esm/protocols/governance/return-stake.mjs +211 -0
  49. package/esm/protocols/governance/revoke-stake.d.mts +27 -0
  50. package/esm/protocols/governance/revoke-stake.mjs +178 -0
  51. package/esm/protocols/governance/slash-stake.d.mts +17 -0
  52. package/esm/protocols/governance/slash-stake.mjs +213 -0
  53. package/esm/protocols/governance/stake.d.mts +15 -0
  54. package/esm/protocols/governance/stake.mjs +270 -0
  55. package/esm/protocols/rollup/claim-reward.d.mts +11 -0
  56. package/esm/protocols/rollup/claim-reward.mjs +322 -0
  57. package/esm/protocols/rollup/close.d.mts +4 -0
  58. package/esm/protocols/rollup/close.mjs +105 -0
  59. package/esm/protocols/rollup/create-block.d.mts +11 -0
  60. package/esm/protocols/rollup/create-block.mjs +303 -0
  61. package/esm/protocols/rollup/create.d.mts +4 -0
  62. package/esm/protocols/rollup/create.mjs +164 -0
  63. package/esm/protocols/rollup/join.d.mts +4 -0
  64. package/esm/protocols/rollup/join.mjs +152 -0
  65. package/esm/protocols/rollup/leave.d.mts +4 -0
  66. package/esm/protocols/rollup/leave.mjs +137 -0
  67. package/esm/protocols/rollup/migrate.d.mts +4 -0
  68. package/esm/protocols/rollup/migrate.mjs +85 -0
  69. package/esm/protocols/rollup/pause.d.mts +4 -0
  70. package/esm/protocols/rollup/pause.mjs +76 -0
  71. package/esm/protocols/rollup/pipes/ensure-validator.d.mts +6 -0
  72. package/esm/protocols/rollup/pipes/ensure-validator.mjs +12 -0
  73. package/esm/protocols/rollup/pipes/verify-evidence.d.mts +15 -0
  74. package/esm/protocols/rollup/pipes/verify-evidence.mjs +29 -0
  75. package/esm/protocols/rollup/pipes/verify-signers.d.mts +15 -0
  76. package/esm/protocols/rollup/pipes/verify-signers.mjs +36 -0
  77. package/esm/protocols/rollup/pipes/verify-status.d.mts +13 -0
  78. package/esm/protocols/rollup/pipes/verify-status.mjs +26 -0
  79. package/esm/protocols/rollup/resume.d.mts +4 -0
  80. package/esm/protocols/rollup/resume.mjs +79 -0
  81. package/esm/protocols/rollup/update.d.mts +4 -0
  82. package/esm/protocols/rollup/update.mjs +111 -0
  83. package/esm/protocols/token/create.d.mts +4 -0
  84. package/esm/protocols/token/create.mjs +150 -0
  85. package/esm/protocols/token/deposit-v2.d.mts +11 -0
  86. package/esm/protocols/token/deposit-v2.mjs +216 -0
  87. package/esm/protocols/token/withdraw-v2.d.mts +9 -0
  88. package/esm/protocols/token/withdraw-v2.mjs +222 -0
  89. package/esm/protocols/token-factory/burn.d.mts +15 -0
  90. package/esm/protocols/token-factory/burn.mjs +233 -0
  91. package/esm/protocols/token-factory/create.d.mts +4 -0
  92. package/esm/protocols/token-factory/create.mjs +254 -0
  93. package/esm/protocols/token-factory/mint.d.mts +15 -0
  94. package/esm/protocols/token-factory/mint.mjs +234 -0
  95. package/esm/protocols/token-factory/pipes/calc-reserve.d.mts +21 -0
  96. package/esm/protocols/token-factory/pipes/calc-reserve.mjs +34 -0
  97. package/esm/protocols/token-factory/pipes/verify-icon.d.mts +14 -0
  98. package/esm/protocols/token-factory/pipes/verify-icon.mjs +18 -0
  99. package/esm/protocols/token-factory/pipes/verify-ownership.d.mts +12 -0
  100. package/esm/protocols/token-factory/pipes/verify-ownership.mjs +63 -0
  101. package/esm/protocols/token-factory/pipes/verify-url.d.mts +12 -0
  102. package/esm/protocols/token-factory/pipes/verify-url.mjs +26 -0
  103. package/esm/protocols/token-factory/update.d.mts +10 -0
  104. package/esm/protocols/token-factory/update.mjs +152 -0
  105. package/esm/protocols/trade/exchange-v2.d.mts +9 -0
  106. package/esm/protocols/trade/exchange-v2.mjs +239 -0
  107. package/esm/protocols/trade/transfer-v2.d.mts +9 -0
  108. package/esm/protocols/trade/transfer-v2.mjs +226 -0
  109. package/esm/protocols/trade/transfer-v3.d.mts +17 -0
  110. package/esm/protocols/trade/transfer-v3.mjs +270 -0
  111. package/esm/util.d.mts +141 -0
  112. package/esm/util.mjs +278 -0
  113. package/lib/_virtual/rolldown_runtime.cjs +29 -0
  114. package/lib/execute.cjs +231 -0
  115. package/lib/execute.d.cts +53 -0
  116. package/lib/index.cjs +105 -0
  117. package/lib/index.d.cts +95 -0
  118. package/lib/pipes/ensure-cost.cjs +141 -0
  119. package/lib/pipes/ensure-cost.d.cts +18 -0
  120. package/lib/pipes/ensure-gas.cjs +41 -0
  121. package/lib/pipes/ensure-gas.d.cts +14 -0
  122. package/lib/protocols/account/delegate.cjs +201 -0
  123. package/lib/protocols/account/delegate.d.cts +4 -0
  124. package/lib/protocols/account/migrate.cjs +135 -0
  125. package/lib/protocols/account/migrate.d.cts +4 -0
  126. package/lib/protocols/account/revoke-delegate.cjs +107 -0
  127. package/lib/protocols/account/revoke-delegate.d.cts +4 -0
  128. package/lib/protocols/asset/acquire-v2.cjs +216 -0
  129. package/lib/protocols/asset/acquire-v2.d.cts +9 -0
  130. package/lib/protocols/asset/acquire-v3.cjs +269 -0
  131. package/lib/protocols/asset/acquire-v3.d.cts +17 -0
  132. package/lib/protocols/asset/calls/transfer-token.cjs +40 -0
  133. package/lib/protocols/asset/calls/transfer-token.d.cts +4 -0
  134. package/lib/protocols/asset/calls/transfer.cjs +35 -0
  135. package/lib/protocols/asset/calls/transfer.d.cts +4 -0
  136. package/lib/protocols/asset/consume.cjs +95 -0
  137. package/lib/protocols/asset/consume.d.cts +4 -0
  138. package/lib/protocols/asset/create.cjs +140 -0
  139. package/lib/protocols/asset/create.d.cts +4 -0
  140. package/lib/protocols/asset/mint.cjs +159 -0
  141. package/lib/protocols/asset/mint.d.cts +4 -0
  142. package/lib/protocols/asset/pipes/exec-mint-hook.cjs +57 -0
  143. package/lib/protocols/asset/pipes/exec-mint-hook.d.cts +24 -0
  144. package/lib/protocols/asset/pipes/extract-factory-tokens.cjs +25 -0
  145. package/lib/protocols/asset/pipes/extract-factory-tokens.d.cts +21 -0
  146. package/lib/protocols/asset/pipes/verify-itx-address.cjs +59 -0
  147. package/lib/protocols/asset/pipes/verify-itx-address.d.cts +32 -0
  148. package/lib/protocols/asset/pipes/verify-itx-assets.cjs +29 -0
  149. package/lib/protocols/asset/pipes/verify-itx-assets.d.cts +18 -0
  150. package/lib/protocols/asset/pipes/verify-itx-variables.cjs +22 -0
  151. package/lib/protocols/asset/pipes/verify-itx-variables.d.cts +17 -0
  152. package/lib/protocols/asset/pipes/verify-mint-limit.cjs +16 -0
  153. package/lib/protocols/asset/pipes/verify-mint-limit.d.cts +15 -0
  154. package/lib/protocols/asset/update.cjs +114 -0
  155. package/lib/protocols/asset/update.d.cts +4 -0
  156. package/lib/protocols/factory/create.cjs +161 -0
  157. package/lib/protocols/factory/create.d.cts +29 -0
  158. package/lib/protocols/governance/claim-stake.cjs +223 -0
  159. package/lib/protocols/governance/claim-stake.d.cts +27 -0
  160. package/lib/protocols/governance/return-stake.cjs +215 -0
  161. package/lib/protocols/governance/return-stake.d.cts +27 -0
  162. package/lib/protocols/governance/revoke-stake.cjs +182 -0
  163. package/lib/protocols/governance/revoke-stake.d.cts +27 -0
  164. package/lib/protocols/governance/slash-stake.cjs +217 -0
  165. package/lib/protocols/governance/slash-stake.d.cts +17 -0
  166. package/lib/protocols/governance/stake.cjs +275 -0
  167. package/lib/protocols/governance/stake.d.cts +15 -0
  168. package/lib/protocols/rollup/claim-reward.cjs +328 -0
  169. package/lib/protocols/rollup/claim-reward.d.cts +11 -0
  170. package/lib/protocols/rollup/close.cjs +107 -0
  171. package/lib/protocols/rollup/close.d.cts +4 -0
  172. package/lib/protocols/rollup/create-block.cjs +309 -0
  173. package/lib/protocols/rollup/create-block.d.cts +11 -0
  174. package/lib/protocols/rollup/create.cjs +169 -0
  175. package/lib/protocols/rollup/create.d.cts +4 -0
  176. package/lib/protocols/rollup/join.cjs +157 -0
  177. package/lib/protocols/rollup/join.d.cts +4 -0
  178. package/lib/protocols/rollup/leave.cjs +141 -0
  179. package/lib/protocols/rollup/leave.d.cts +4 -0
  180. package/lib/protocols/rollup/migrate.cjs +87 -0
  181. package/lib/protocols/rollup/migrate.d.cts +4 -0
  182. package/lib/protocols/rollup/pause.cjs +78 -0
  183. package/lib/protocols/rollup/pause.d.cts +4 -0
  184. package/lib/protocols/rollup/pipes/ensure-validator.cjs +14 -0
  185. package/lib/protocols/rollup/pipes/ensure-validator.d.cts +6 -0
  186. package/lib/protocols/rollup/pipes/verify-evidence.cjs +32 -0
  187. package/lib/protocols/rollup/pipes/verify-evidence.d.cts +15 -0
  188. package/lib/protocols/rollup/pipes/verify-signers.cjs +39 -0
  189. package/lib/protocols/rollup/pipes/verify-signers.d.cts +15 -0
  190. package/lib/protocols/rollup/pipes/verify-status.cjs +28 -0
  191. package/lib/protocols/rollup/pipes/verify-status.d.cts +13 -0
  192. package/lib/protocols/rollup/resume.cjs +81 -0
  193. package/lib/protocols/rollup/resume.d.cts +4 -0
  194. package/lib/protocols/rollup/update.cjs +114 -0
  195. package/lib/protocols/rollup/update.d.cts +4 -0
  196. package/lib/protocols/token/create.cjs +156 -0
  197. package/lib/protocols/token/create.d.cts +4 -0
  198. package/lib/protocols/token/deposit-v2.cjs +219 -0
  199. package/lib/protocols/token/deposit-v2.d.cts +11 -0
  200. package/lib/protocols/token/withdraw-v2.cjs +225 -0
  201. package/lib/protocols/token/withdraw-v2.d.cts +9 -0
  202. package/lib/protocols/token-factory/burn.cjs +236 -0
  203. package/lib/protocols/token-factory/burn.d.cts +15 -0
  204. package/lib/protocols/token-factory/create.cjs +260 -0
  205. package/lib/protocols/token-factory/create.d.cts +4 -0
  206. package/lib/protocols/token-factory/mint.cjs +237 -0
  207. package/lib/protocols/token-factory/mint.d.cts +15 -0
  208. package/lib/protocols/token-factory/pipes/calc-reserve.cjs +38 -0
  209. package/lib/protocols/token-factory/pipes/calc-reserve.d.cts +21 -0
  210. package/lib/protocols/token-factory/pipes/verify-icon.cjs +22 -0
  211. package/lib/protocols/token-factory/pipes/verify-icon.d.cts +14 -0
  212. package/lib/protocols/token-factory/pipes/verify-ownership.cjs +66 -0
  213. package/lib/protocols/token-factory/pipes/verify-ownership.d.cts +12 -0
  214. package/lib/protocols/token-factory/pipes/verify-url.cjs +29 -0
  215. package/lib/protocols/token-factory/pipes/verify-url.d.cts +12 -0
  216. package/lib/protocols/token-factory/update.cjs +155 -0
  217. package/lib/protocols/token-factory/update.d.cts +10 -0
  218. package/lib/protocols/trade/exchange-v2.cjs +243 -0
  219. package/lib/protocols/trade/exchange-v2.d.cts +9 -0
  220. package/lib/protocols/trade/transfer-v2.cjs +229 -0
  221. package/lib/protocols/trade/transfer-v2.d.cts +9 -0
  222. package/lib/protocols/trade/transfer-v3.cjs +274 -0
  223. package/lib/protocols/trade/transfer-v3.d.cts +17 -0
  224. package/lib/util.cjs +296 -0
  225. package/lib/util.d.cts +141 -0
  226. package/package.json +49 -22
  227. package/tools/fixtures.ts +564 -0
  228. package/lib/execute.js +0 -254
  229. package/lib/index.js +0 -117
  230. package/lib/pipes/ensure-cost.js +0 -193
  231. package/lib/pipes/ensure-gas.js +0 -48
  232. package/lib/protocols/account/delegate.js +0 -223
  233. package/lib/protocols/account/migrate.js +0 -153
  234. package/lib/protocols/account/revoke-delegate.js +0 -110
  235. package/lib/protocols/asset/acquire-v2.js +0 -262
  236. package/lib/protocols/asset/acquire-v3.js +0 -330
  237. package/lib/protocols/asset/calls/README.md +0 -5
  238. package/lib/protocols/asset/calls/transfer-token.js +0 -36
  239. package/lib/protocols/asset/calls/transfer.js +0 -28
  240. package/lib/protocols/asset/consume.js +0 -105
  241. package/lib/protocols/asset/create.js +0 -151
  242. package/lib/protocols/asset/mint.js +0 -199
  243. package/lib/protocols/asset/pipes/exec-mint-hook.js +0 -62
  244. package/lib/protocols/asset/pipes/extract-factory-tokens.js +0 -18
  245. package/lib/protocols/asset/pipes/verify-itx-address.js +0 -54
  246. package/lib/protocols/asset/pipes/verify-itx-assets.js +0 -51
  247. package/lib/protocols/asset/pipes/verify-itx-variables.js +0 -26
  248. package/lib/protocols/asset/pipes/verify-mint-limit.js +0 -13
  249. package/lib/protocols/asset/update.js +0 -131
  250. package/lib/protocols/factory/create.js +0 -191
  251. package/lib/protocols/governance/claim-stake.js +0 -266
  252. package/lib/protocols/governance/return-stake.js +0 -248
  253. package/lib/protocols/governance/revoke-stake.js +0 -172
  254. package/lib/protocols/governance/slash-stake.js +0 -271
  255. package/lib/protocols/governance/stake.js +0 -303
  256. package/lib/protocols/rollup/claim-reward.js +0 -342
  257. package/lib/protocols/rollup/close.js +0 -104
  258. package/lib/protocols/rollup/create-block.js +0 -413
  259. package/lib/protocols/rollup/create.js +0 -197
  260. package/lib/protocols/rollup/join.js +0 -182
  261. package/lib/protocols/rollup/leave.js +0 -145
  262. package/lib/protocols/rollup/migrate.js +0 -85
  263. package/lib/protocols/rollup/pause.js +0 -75
  264. package/lib/protocols/rollup/pipes/ensure-validator.js +0 -12
  265. package/lib/protocols/rollup/pipes/verify-evidence.js +0 -37
  266. package/lib/protocols/rollup/pipes/verify-signers.js +0 -87
  267. package/lib/protocols/rollup/pipes/verify-status.js +0 -30
  268. package/lib/protocols/rollup/resume.js +0 -75
  269. package/lib/protocols/rollup/update.js +0 -122
  270. package/lib/protocols/token/create.js +0 -199
  271. package/lib/protocols/token/deposit-v2.js +0 -290
  272. package/lib/protocols/token/withdraw-v2.js +0 -305
  273. package/lib/protocols/token-factory/burn.js +0 -371
  274. package/lib/protocols/token-factory/create.js +0 -342
  275. package/lib/protocols/token-factory/mint.js +0 -385
  276. package/lib/protocols/token-factory/pipes/calc-reserve.js +0 -37
  277. package/lib/protocols/token-factory/pipes/verify-icon.js +0 -27
  278. package/lib/protocols/token-factory/pipes/verify-ownership.js +0 -93
  279. package/lib/protocols/token-factory/pipes/verify-url.js +0 -32
  280. package/lib/protocols/token-factory/update.js +0 -208
  281. package/lib/protocols/trade/exchange-v2.js +0 -239
  282. package/lib/protocols/trade/transfer-v2.js +0 -233
  283. package/lib/protocols/trade/transfer-v3.js +0 -333
  284. package/lib/util.js +0 -442
@@ -1,371 +0,0 @@
1
- const { CustomError: Error } = require('@ocap/util/lib/error');
2
- const { Joi, schemas } = require('@arcblock/validator');
3
- const { BN, fromUnitToToken } = require('@ocap/util');
4
- const { Runner, pipes } = require('@ocap/tx-pipeline');
5
- const { account, tokenFactory, token } = require('@ocap/state');
6
- const pick = require('lodash/pick');
7
-
8
- const EnsureTxGas = require('../../pipes/ensure-gas');
9
- const EnsureTxCost = require('../../pipes/ensure-cost');
10
- const CalcReserve = require('./pipes/calc-reserve');
11
- const { applyTokenChange, applyTokenUpdates } = require('../../util');
12
-
13
- const runner = new Runner();
14
-
15
- const schema = Joi.object({
16
- tokenFactory: Joi.DID().prefix().role('ROLE_TOKEN_FACTORY').required(),
17
- receiver: schemas.tokenHolder.required(),
18
- minReserve: Joi.alternatives().try(Joi.BN().greater(0), Joi.equal('')).optional(),
19
- inputsList: schemas.multiInput.min(1).required(),
20
- data: Joi.any().optional().allow(null),
21
- }).options({ stripUnknown: true, noDefaults: false });
22
-
23
- // verify itx
24
- runner.use(({ itx }, next) => {
25
- const { error } = schema.validate(itx);
26
- if (error) {
27
- return next(new Error('INVALID_TX', `Invalid itx: ${error.message}`));
28
- }
29
- return next();
30
- });
31
-
32
- // verify token factory
33
- runner.use(
34
- pipes.ExtractState({
35
- from: 'itx.tokenFactory',
36
- to: 'tokenFactoryState',
37
- status: 'INVALID_TOKEN_FACTORY',
38
- table: 'tokenFactory',
39
- })
40
- );
41
-
42
- // ensure token state
43
- runner.use(
44
- pipes.ExtractState({
45
- from: 'tokenFactoryState.tokenAddress',
46
- to: 'tokenState',
47
- status: 'INVALID_TOKEN',
48
- table: 'token',
49
- })
50
- );
51
-
52
- // verify inputs
53
- runner.use(
54
- pipes.VerifyTxInput({
55
- fieldKey: 'itx.inputs',
56
- inputsKey: 'inputs',
57
- sendersKey: 'senders',
58
- tokensKey: 'tokens',
59
- assetsKey: null,
60
- })
61
- );
62
-
63
- // verify itx size: set hard limit here because more inputs leads to longer tx execute time
64
- runner.use(pipes.VerifyListSize({ listKey: ['inputs', 'senders', 'tokens', 'assets'] }));
65
-
66
- // verify multi sig
67
- runner.use(pipes.VerifyMultiSigV2({ signersKey: 'senders' }));
68
-
69
- // verify inputs token
70
- runner.use((context, next) => {
71
- const { tokenFactoryState, inputs } = context;
72
-
73
- const isAccepted = inputs.every(
74
- (input) =>
75
- input.tokensList.length &&
76
- input.tokensList.every((x) => x.address === tokenFactoryState.tokenAddress) &&
77
- !input.assetsList.length
78
- );
79
-
80
- if (!isAccepted) {
81
- return next(new Error('INVALID_TX', `Inputs only accept ${tokenFactoryState.tokenAddress}`));
82
- }
83
-
84
- return next();
85
- });
86
-
87
- // ensure sender
88
- runner.use(pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'OK', table: 'account' }));
89
- runner.use(pipes.VerifyAccountMigration({ stateKey: 'senderState', addressKey: 'tx.from' }));
90
-
91
- runner.use(
92
- pipes.ExtractState({ from: 'senders', to: 'signerStates', status: 'INVALID_SIGNER_STATE', table: 'account' })
93
- );
94
- runner.use(pipes.VerifyAccountMigration({ signerKey: 'signerStates', stateKey: 'senderState', addressKey: 'tx.from' }));
95
-
96
- // ensure receiver
97
- runner.use(pipes.ExtractState({ from: 'itx.receiver', to: 'receiverState', status: 'OK', table: 'account' }));
98
- runner.use(pipes.VerifyAccountMigration({ stateKey: 'receiverState', addressKey: 'itx.receiver' }));
99
-
100
- // verify blocked
101
- runner.use(pipes.VerifyBlocked({ stateKeys: ['signerStates', 'receiverState'] }));
102
-
103
- // ensure owner
104
- runner.use(
105
- pipes.ExtractState({
106
- from: 'tokenFactoryState.owner',
107
- to: 'ownerState',
108
- status: 'INVALID_OWNER_STATE',
109
- table: 'account',
110
- })
111
- );
112
-
113
- // verify minters restriction
114
- runner.use(
115
- pipes.verifyTokenAccess({
116
- statesKey: 'tokenState',
117
- listFieldKey: 'minters',
118
- accountKeys: ['senderState'],
119
- errorMessage: 'Account {address} is not allowed to burn token {tokenAddress}',
120
- })
121
- );
122
-
123
- // calculate burn amount
124
- runner.use((context, next) => {
125
- const { inputs, tokenFactoryState } = context;
126
- let amount = new BN('0');
127
-
128
- for (const { tokensList } of inputs) {
129
- const delta = tokensList.find((x) => x.address === tokenFactoryState.tokenAddress)?.value;
130
- if (!delta) {
131
- return next(new Error('INVALID_TX', 'Invalid inputs'));
132
- }
133
- amount = amount.add(new BN(delta));
134
- }
135
-
136
- context.burnAmount = amount.toString();
137
-
138
- return next();
139
- });
140
-
141
- // calculate reserve amount / fee
142
- runner.use(
143
- CalcReserve({
144
- tokenFactoryKey: 'tokenFactoryState',
145
- tokenStateKey: 'tokenState',
146
- reserveKey: 'reserveAmount',
147
- feeKey: 'reserveFee',
148
- amountKey: 'burnAmount',
149
- direction: 'burn',
150
- }),
151
- { shouldSkip: ({ tokenFactoryState }) => !tokenFactoryState.curve }
152
- );
153
-
154
- // verify slippage
155
- runner.use(
156
- (context, next) => {
157
- const { reserveAmount, reserveFee } = context;
158
- const { minReserve } = context.itx;
159
-
160
- if (minReserve && new BN(reserveAmount).lt(new BN(minReserve).add(new BN(reserveFee || '0')))) {
161
- return next(
162
- new Error(
163
- 'SLIPPAGE_EXCEEDED',
164
- `Burn token failed due to price movement. Expected minimum: ${fromUnitToToken(minReserve)}, actual: ${fromUnitToToken(reserveAmount)}. Try reducing your minReserve.`
165
- )
166
- );
167
- }
168
-
169
- return next();
170
- },
171
- { shouldSkip: ({ tokenFactoryState }) => !tokenFactoryState.curve }
172
- );
173
-
174
- // verify balance
175
- runner.use(pipes.ExtractState({ from: 'tokens', to: 'tokenStates', status: 'INVALID_TOKEN', table: 'token' }));
176
- runner.use(pipes.VerifyTokenBalance({ ownerKey: 'signerStates', conditionKey: 'inputs' }));
177
-
178
- // verify token factory balance
179
- runner.use((context, next) => {
180
- const { tokenFactoryState } = context;
181
- if (new BN(tokenFactoryState.currentSupply).lt(new BN(context.burnAmount))) {
182
- return next(new Error('INSUFFICIENT_FUND', 'Token factory supply is not enough'));
183
- }
184
- if (new BN(tokenFactoryState.reserveBalance).lt(new BN(context.reserveAmount || '0'))) {
185
- return next(new Error('INSUFFICIENT_FUND', 'Token factory reserve balance is not enough'));
186
- }
187
- return next();
188
- });
189
-
190
- // Ensure tx fee and gas
191
- runner.use(
192
- EnsureTxGas((context) => {
193
- const result = { create: 0, update: 2, payment: 0 };
194
-
195
- if (context.senderState) {
196
- result.update += 1;
197
- } else {
198
- result.create += 1;
199
- }
200
-
201
- if (context.tokenFactoryState.curve) {
202
- if (context.receiverState) {
203
- result.update += 1;
204
- } else {
205
- result.create += 1;
206
- }
207
- }
208
-
209
- if (context.reserveFee) {
210
- result.update += 1; // owner
211
- }
212
-
213
- if (context.signerStates) {
214
- result.update += context.signerStates.length;
215
- }
216
-
217
- return result;
218
- })
219
- );
220
- runner.use(EnsureTxCost({ attachSenderChanges: true }));
221
-
222
- // Save context snapshot before updating states
223
- runner.use(pipes.TakeStateSnapshot());
224
-
225
- // update statedb: transfer tokens to new owner
226
- runner.use(
227
- async (context, next) => {
228
- const {
229
- tx,
230
- senderState,
231
- receiverState,
232
- ownerState,
233
- statedb,
234
- senderChange,
235
- updateVaults,
236
- tokenFactoryState,
237
- tokenState,
238
- reserveAmount,
239
- reserveFee,
240
- itx,
241
- inputs,
242
- signerStates,
243
- burnAmount,
244
- } = context;
245
- const { receiver } = itx;
246
- const { reserveAddress, tokenAddress } = tokenFactoryState;
247
-
248
- const accountUpdates = {};
249
- const inputChanges = [];
250
-
251
- // update signer burns
252
- inputs.forEach(({ owner, tokensList }) => {
253
- const tokenChange = tokensList.find((item) => item.address === tokenAddress);
254
-
255
- accountUpdates[owner] = applyTokenUpdates(
256
- [tokenChange],
257
- signerStates.find((s) => s.address === owner),
258
- 'sub'
259
- );
260
-
261
- inputChanges.push({
262
- address: owner,
263
- token: tokenAddress,
264
- delta: new BN(tokenChange.value).neg().toString(),
265
- });
266
- });
267
-
268
- // Ensure the sender exists in accountUpdates, because even if there is no balance change, we need to update his nonce
269
- if (!accountUpdates[tx.from]) {
270
- accountUpdates[tx.from] = senderState || {};
271
- }
272
-
273
- // update owner
274
- if (reserveFee && new BN(reserveFee).gt(0)) {
275
- accountUpdates[ownerState.address] = applyTokenChange(accountUpdates[ownerState.address] || ownerState, {
276
- address: ownerState.address,
277
- token: reserveAddress,
278
- delta: reserveFee,
279
- });
280
- }
281
-
282
- // update receiver
283
- // should not update receiver for credit token
284
- if (tokenFactoryState.curve) {
285
- accountUpdates[receiver] = applyTokenChange(
286
- accountUpdates[receiver] || receiverState || { address: receiver, tokens: {} },
287
- {
288
- address: receiver,
289
- token: reserveAddress,
290
- delta: new BN(reserveAmount).sub(new BN(reserveFee || '0')).toString(), // reserveAmount - reserveFee
291
- }
292
- );
293
- }
294
-
295
- // update sender
296
- if (senderChange) {
297
- accountUpdates[senderChange.address] = applyTokenChange(
298
- accountUpdates[senderChange.address] || senderState,
299
- senderChange
300
- );
301
- }
302
-
303
- const [newAccountStates, newTokenFactoryState, newTokenState] = await Promise.all([
304
- // update accounts
305
- Promise.all(
306
- Object.entries(accountUpdates).map(([address, updates]) => {
307
- // We can use updateOrCreate here because the owner and signer have already been validated to exist earlier,
308
- // the sender and receiver are allowed to be created in the transaction.
309
- const state = [senderState, receiverState, ownerState, ...signerStates].find((x) => x?.address === address);
310
-
311
- // Should only update nonce and pk for sender and new accounts
312
- const actualUpdates = state ? pick(updates, ['tokens']) : { ...updates, address };
313
-
314
- // Should only update nonce and pk for sender
315
- if (address === tx.from) {
316
- actualUpdates.pk = tx.pk;
317
- actualUpdates.nonce = tx.nonce;
318
- }
319
-
320
- return statedb.account.updateOrCreate(state, account.updateOrCreate(state, actualUpdates, context), context);
321
- })
322
- ),
323
-
324
- // Update token factory state
325
- statedb.tokenFactory.update(
326
- tokenFactoryState.address,
327
- tokenFactory.update(
328
- tokenFactoryState,
329
- {
330
- currentSupply: new BN(tokenFactoryState.currentSupply).sub(new BN(burnAmount)).toString(),
331
- reserveBalance: new BN(tokenFactoryState.reserveBalance).sub(new BN(reserveAmount || '0')).toString(),
332
- },
333
- context
334
- ),
335
- context
336
- ),
337
-
338
- statedb.token.update(
339
- tokenAddress,
340
- token.update(
341
- tokenState,
342
- {
343
- totalSupply: new BN(tokenState.totalSupply).sub(new BN(burnAmount)).toString(),
344
- },
345
- context
346
- ),
347
- context
348
- ),
349
- ]);
350
-
351
- context.senderState = newAccountStates.find((x) => x.address === tx.from);
352
- context.receiverState = newAccountStates.find((x) => x.address === receiver);
353
- // owner maybe not updated
354
- context.ownerState = newAccountStates.find((x) => x.address === ownerState.address) || ownerState;
355
- context.signerStates = newAccountStates.filter((x) => signerStates.find((s) => s.address === x.address));
356
- context.tokenFactoryState = newTokenFactoryState;
357
- context.tokenState = newTokenState;
358
-
359
- // save this for receipt generation
360
- context.inputChanges = inputChanges;
361
-
362
- await updateVaults();
363
-
364
- next();
365
- },
366
- { persistError: true }
367
- );
368
-
369
- runner.use(pipes.VerifyStateDiff());
370
-
371
- module.exports = runner;
@@ -1,342 +0,0 @@
1
- const isEmpty = require('empty-value');
2
- const cloneDeep = require('lodash/cloneDeep');
3
- const uniq = require('lodash/uniq');
4
- const { Joi } = require('@arcblock/validator');
5
- const { CustomError: Error } = require('@ocap/util/lib/error');
6
- const { Runner, pipes } = require('@ocap/tx-pipeline');
7
- const { account, token, tokenFactory, delegation, stake } = require('@ocap/state');
8
- const { toTokenFactoryAddress, toTokenAddress, toStakeAddress } = require('@arcblock/did-util');
9
- const { BN, fromTokenToUnit, fromUnitToToken } = require('@ocap/util');
10
-
11
- const debug = require('debug')(`${require('../../../package.json').name}:create-token-factory`);
12
- const { applyTokenChange, decodeAnySafe, getDelegationRequirements } = require('../../util');
13
-
14
- const EnsureTxGas = require('../../pipes/ensure-gas');
15
- const EnsureTxCost = require('../../pipes/ensure-cost');
16
- const verifyIcon = require('./pipes/verify-icon');
17
- const verifyUrl = require('./pipes/verify-url');
18
- const verifyOwnership = require('./pipes/verify-ownership');
19
-
20
- const runner = new Runner();
21
-
22
- const isTest = process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test' || process.env.CI;
23
-
24
- runner.use(pipes.VerifyMultiSig(0));
25
-
26
- const schema = Joi.object({
27
- address: Joi.DID().prefix().role('ROLE_TOKEN_FACTORY').required(),
28
- feeRate: Joi.number().min(0).max(2000).required(),
29
- curve: Joi.when('token.type', {
30
- is: 'CreditToken',
31
- then: Joi.valid(null).optional().messages({
32
- 'any.only': 'Should not provide curve for CreditToken',
33
- }),
34
- otherwise: tokenFactory.curveSchema.required(),
35
- }),
36
- reserveAddress: Joi.DID().prefix().role('ROLE_TOKEN').required(),
37
- token: Joi.object({
38
- name: Joi.string().min(1).max(32).required(),
39
- description: Joi.string().min(16).max(128).required(),
40
- symbol: Joi.string().min(2).max(6).uppercase().required(),
41
- unit: Joi.string().min(1).max(6).lowercase().required(),
42
- decimal: Joi.number().min(2).max(18).required(),
43
- icon: Joi.string().optional().allow(null, ''),
44
- maxTotalSupply: Joi.alternatives().try(Joi.BN().greater(0), Joi.string().valid('')).optional().allow(null),
45
- website: Joi.string()
46
- .uri({
47
- scheme: isTest ? ['http', 'https'] : ['https'],
48
- allowRelative: false,
49
- })
50
- .max(256)
51
- .optional()
52
- .allow(null, ''),
53
- metadata: Joi.any().required(),
54
- spendersList: Joi.array().items(Joi.DID().prefix()).max(30).optional().allow(null).default(null),
55
- mintersList: Joi.array().items(Joi.DID().prefix()).max(30).optional().allow(null).default(null),
56
- type: Joi.string().valid('CreditToken', 'BondingCurveToken').required(),
57
- }).required(),
58
- data: Joi.any().optional().allow(null),
59
- }).options({ stripUnknown: true, noDefaults: false });
60
-
61
- // 1. verify itx
62
- runner.use((context, next) => {
63
- const { error, value } = schema.validate(context.itx);
64
- if (error) {
65
- return next(new Error('INVALID_TX', `Invalid itx: ${error.message}`));
66
- }
67
-
68
- // filter by curve type
69
- context.itx.curve = value.curve;
70
-
71
- // decode and verify metadata
72
- if (context.itx.token.metadata) {
73
- const metadata = decodeAnySafe(context.itx.token.metadata);
74
- const { error: metadataError, value: metadataValue } = token.metadataSchema.validate(metadata.value);
75
- if (metadataError) {
76
- return next(new Error('INVALID_TX', `Invalid metadata: ${metadataError.message}`));
77
- }
78
- context.itx.token.metadata = { ...metadata, value: metadataValue };
79
- }
80
-
81
- // convert spendersList to spenders
82
- context.itx.token.spenders = value.token.spendersList?.length ? uniq(value.token.spendersList) : null;
83
- delete context.itx.token.spendersList;
84
-
85
- // convert mintersList to minters
86
- context.itx.token.minters = value.token.mintersList?.length ? uniq(value.token.mintersList) : null;
87
- delete context.itx.token.mintersList;
88
-
89
- return next();
90
- });
91
-
92
- runner.use(
93
- pipes.VerifyInfo([
94
- // verify token address is valid
95
- {
96
- error: 'INVALID_TOKEN',
97
- message: 'Token address is not valid',
98
- fn: (context) => {
99
- return toTokenAddress({ ...context.itx.token, address: '' }) === context.itx.token.address;
100
- },
101
- },
102
- // verify token factory address is valid
103
- {
104
- error: 'INVALID_TOKEN_FACTORY',
105
- message: 'Token factory address is not valid',
106
- fn: (context) => {
107
- const itx = cloneDeep(context.itx);
108
- itx.data = decodeAnySafe(itx.data);
109
- itx.address = '';
110
-
111
- return toTokenFactoryAddress(itx) === context.itx.address;
112
- },
113
- },
114
- // verify reserve address is config.token.address
115
- {
116
- error: 'INVALID_RESERVE_ADDRESS',
117
- message: 'Reserve address is not valid',
118
- fn: (context) => context.itx.reserveAddress === context.config.token.address,
119
- },
120
- ])
121
- );
122
-
123
- runner.use(verifyIcon());
124
- runner.use(verifyUrl({ urlKeys: ['itx.token.website', 'itx.token.metadata.value.communityUrl'] }));
125
- runner.use(verifyOwnership({ tokenKey: 'itx.token' }));
126
-
127
- // Ensure symbol is not internal
128
- runner.use((context, next) => {
129
- const { reservedSymbols } = context.config;
130
- const { symbol } = context.itx.token;
131
-
132
- if (reservedSymbols.includes(symbol.toUpperCase())) {
133
- return next(new Error('INVALID_SYMBOL', `Token symbol can not be ${symbol}`));
134
- }
135
-
136
- return next();
137
- });
138
-
139
- // Ensure token factory not exist
140
- runner.use(pipes.ExtractState({ from: 'itx.address', to: 'tokenFactoryState', table: 'tokenFactory', status: 'OK' }));
141
- runner.use(
142
- pipes.VerifyInfo([
143
- {
144
- error: 'DUPLICATE_TOKEN_FACTORY',
145
- message: 'Token factory address already exists on chain',
146
- fn: (context) => isEmpty(context.tokenFactoryState),
147
- },
148
- ])
149
- );
150
-
151
- // Ensure token not exist
152
- runner.use(pipes.ExtractState({ from: 'itx.token.address', to: 'tokenState', table: 'token', status: 'OK' }));
153
- runner.use(
154
- pipes.VerifyInfo([
155
- {
156
- error: 'DUPLICATE_TOKEN',
157
- message: 'Token address already exists on chain',
158
- fn: (context) => isEmpty(context.tokenState),
159
- },
160
- ])
161
- );
162
-
163
- // Ensure sender exist
164
- runner.use(
165
- pipes.ExtractState({ from: 'tx.from', to: 'senderState', status: 'INVALID_SENDER_STATE', table: 'account' })
166
- );
167
- runner.use(pipes.VerifyAccountMigration({ stateKey: 'senderState', addressKey: 'tx.from' }));
168
-
169
- runner.use(pipes.VerifyBlocked({ stateKeys: ['senderState'] }));
170
-
171
- // verify staking: get address, extract state, verify amount
172
- runner.use((context, next) => {
173
- const { tx, itx } = context;
174
- // stake from sender to main token
175
- const sender = tx.delegator || tx.from;
176
- const receiver = context.config.token.address;
177
- context.stakeAddress = toStakeAddress(sender, receiver, itx.token.symbol);
178
- return next();
179
- });
180
- runner.use(
181
- pipes.ExtractState({ from: 'stakeAddress', to: 'stakeState', status: 'INVALID_STAKE_STATE', table: 'stake' })
182
- );
183
- runner.use((context, next) => {
184
- const { stakeState, config, itx } = context;
185
-
186
- if (stakeState.revocable === false) {
187
- return next(new Error('INVALID_STAKE_STATE', `Staking for token creating already locked: ${stakeState.address}`));
188
- }
189
-
190
- const actualStake = new BN(stakeState.tokens[config.token.address] || 0);
191
- const requiredStake = fromTokenToUnit(
192
- itx.token.type === 'CreditToken'
193
- ? config.transaction.txStake.createCreditToken
194
- : config.transaction.txStake.createToken,
195
- config.token.decimal
196
- );
197
- if (actualStake.lt(requiredStake)) {
198
- return next(
199
- new Error(
200
- 'INVALID_STAKE_STATE',
201
- `Insufficient stake amount: required ${fromUnitToToken(requiredStake, config.token.decimal)} ${config.token.symbol}`
202
- )
203
- );
204
- }
205
-
206
- return next();
207
- });
208
-
209
- // Ensure delegation
210
- runner.use(pipes.ExtractState({ from: 'tx.delegator', to: 'delegatorState', status: 'OK', table: 'account' }));
211
- runner.use(pipes.VerifyAccountMigration({ stateKey: 'delegatorState', addressKey: 'tx.delegator' }));
212
- runner.use(
213
- pipes.VerifyDelegation({
214
- type: 'signature',
215
- signerKey: 'senderState',
216
- delegatorKey: 'delegatorState',
217
- getRequirements: getDelegationRequirements,
218
- })
219
- );
220
-
221
- // Ensure uniqueness of token symbol
222
- runner.use(
223
- async function EnsureTokenSymbol(context, next) {
224
- const itxToken = context.itx.token;
225
-
226
- const exist = await context.statedb.token.existBySymbol(itxToken.symbol, context);
227
- if (exist) {
228
- return next(new Error('DUPLICATE_SYMBOL', 'Token symbol already exists'));
229
- }
230
-
231
- return next();
232
- },
233
- { persistError: true }
234
- );
235
-
236
- // Ensure tx fee and gas
237
- runner.use(
238
- EnsureTxGas((context) => {
239
- const result = { create: 2, update: 2, payment: 0 };
240
-
241
- if (context.isDelegationChanged) {
242
- result.update += 1;
243
- }
244
-
245
- return result;
246
- })
247
- );
248
- runner.use(EnsureTxCost({ attachSenderChanges: true }));
249
-
250
- // Save context snapshot before updating states
251
- runner.use(pipes.TakeStateSnapshot());
252
-
253
- // Update sender state, token factory state, and lock stake
254
- runner.use(
255
- async (context, next) => {
256
- const {
257
- tx,
258
- itx,
259
- statedb,
260
- senderState,
261
- delegatorState,
262
- delegationState,
263
- senderChange,
264
- stakeState,
265
- stakeAddress,
266
- updateVaults,
267
- config,
268
- } = context;
269
- const data = decodeAnySafe(itx.data);
270
- const owner = delegatorState ? delegatorState.address : senderState.address;
271
-
272
- const itxToken = itx.token;
273
-
274
- const { tokens: senderTokens = {} } = senderState;
275
-
276
- const senderUpdates = senderChange
277
- ? applyTokenChange({ tokens: senderTokens }, senderChange)
278
- : { tokens: senderTokens };
279
-
280
- const [newSenderState, newTokenState, newTokenFactoryState, newDelegationState, newStakeState] = await Promise.all([
281
- statedb.account.update(
282
- senderState.address,
283
- account.update(senderState, { nonce: tx.nonce, pk: tx.pk, ...senderUpdates }, context),
284
- context
285
- ),
286
-
287
- statedb.token.create(
288
- itxToken.address,
289
- token.create(
290
- {
291
- ...cloneDeep(itxToken),
292
- totalSupply: '0',
293
- initialSupply: '0',
294
- issuer: owner,
295
- tokenFactoryAddress: itx.address,
296
- },
297
- context
298
- ),
299
- context
300
- ),
301
-
302
- statedb.tokenFactory.create(
303
- itx.address,
304
- tokenFactory.create({ ...cloneDeep(itx), owner, tokenAddress: itxToken.address, data }, context),
305
- context
306
- ),
307
-
308
- // Update delegation state
309
- context.isDelegationChanged
310
- ? statedb.delegation.update(delegationState.address, delegation.update(delegationState, {}, context), context)
311
- : delegationState,
312
-
313
- // Lock the stake after successful token creation
314
- statedb.stake.update(
315
- stakeAddress,
316
- stake.update(
317
- stakeState,
318
- { revocable: false, revokeWaitingPeriod: config.transaction.txStake.createTokenLockPeriod },
319
- context
320
- ),
321
- context
322
- ),
323
- ]);
324
-
325
- await updateVaults();
326
-
327
- context.senderState = newSenderState;
328
- context.tokenState = newTokenState;
329
- context.tokenFactoryState = newTokenFactoryState;
330
- context.delegationState = newDelegationState;
331
- context.stakeState = newStakeState;
332
-
333
- debug('create token factory', newTokenFactoryState);
334
-
335
- next();
336
- },
337
- { persistError: true }
338
- );
339
-
340
- runner.use(pipes.VerifyStateDiff());
341
-
342
- module.exports = runner;