@wishknish/knishio-client-js 0.5.2 → 0.6.1
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/README.md +207 -274
- package/dist/client.iife.js +533 -0
- package/package.json +37 -79
- package/src/.babelrc +0 -22
- package/src/Atom.js +171 -132
- package/src/AtomMeta.js +76 -50
- package/src/AuthToken.js +38 -47
- package/src/KnishIOClient.js +934 -987
- package/src/Meta.js +15 -17
- package/src/Molecule.js +423 -494
- package/src/PolicyMeta.js +32 -41
- package/src/TokenUnit.js +30 -32
- package/src/Wallet.js +275 -265
- package/src/exception/AtomIndexException.js +4 -8
- package/src/exception/AtomsMissingException.js +4 -6
- package/src/exception/AuthorizationRejectedException.js +4 -5
- package/src/exception/BalanceInsufficientException.js +4 -8
- package/src/exception/BaseException.js +6 -8
- package/src/exception/BatchIdException.js +5 -7
- package/src/exception/CodeException.js +4 -8
- package/src/{libraries/ApolloLink/HttpLink.js → exception/DecryptionKeyException.js} +12 -15
- package/src/exception/InvalidResponseException.js +4 -5
- package/src/exception/MetaMissingException.js +4 -6
- package/src/exception/MolecularHashMismatchException.js +4 -6
- package/src/exception/MolecularHashMissingException.js +4 -5
- package/src/exception/NegativeAmountException.js +4 -5
- package/src/exception/PolicyInvalidException.js +4 -4
- package/src/exception/SignatureMalformedException.js +4 -5
- package/src/exception/SignatureMismatchException.js +4 -5
- package/src/exception/StackableUnitAmountException.js +4 -5
- package/src/exception/StackableUnitDecimalsException.js +4 -5
- package/src/exception/TransferBalanceException.js +4 -5
- package/src/exception/TransferMalformedException.js +4 -5
- package/src/exception/TransferMismatchedException.js +4 -5
- package/src/exception/TransferRemainderException.js +4 -5
- package/src/exception/TransferToSelfException.js +4 -5
- package/src/exception/TransferUnbalancedException.js +4 -5
- package/src/exception/UnauthenticatedException.js +4 -5
- package/src/{libraries/ApolloLink/AuthLink.js → exception/WalletCredentialException.js} +12 -40
- package/src/exception/WalletShadowException.js +4 -5
- package/src/exception/WrongTokenTypeException.js +4 -5
- package/src/exception/index.js +26 -26
- package/src/index.js +8 -10
- package/src/instance/Rules/Callback.js +91 -93
- package/src/instance/Rules/Condition.js +21 -23
- package/src/instance/Rules/Meta.js +13 -14
- package/src/instance/Rules/Rule.js +39 -43
- package/src/instance/Rules/exception/RuleArgumentException.js +4 -4
- package/src/libraries/CheckMolecule.js +253 -232
- package/src/libraries/Decimal.js +13 -17
- package/src/libraries/Dot.js +74 -48
- package/src/libraries/Hex.js +49 -54
- package/src/libraries/array.js +50 -41
- package/src/libraries/crypto.js +20 -27
- package/src/libraries/strings.js +58 -91
- package/src/libraries/urql/UrqlClientWrapper.js +166 -0
- package/src/mutation/Mutation.js +44 -25
- package/src/mutation/MutationActiveSession.js +12 -12
- package/src/mutation/MutationClaimShadowWallet.js +15 -17
- package/src/mutation/MutationCreateIdentifier.js +11 -12
- package/src/mutation/MutationCreateMeta.js +11 -12
- package/src/mutation/MutationCreateRule.js +11 -12
- package/src/mutation/MutationCreateToken.js +18 -13
- package/src/mutation/MutationCreateWallet.js +9 -11
- package/src/mutation/MutationDepositBufferToken.js +7 -9
- package/src/mutation/MutationLinkIdentifier.js +12 -14
- package/src/mutation/MutationProposeMolecule.js +24 -25
- package/src/mutation/MutationRequestAuthorization.js +9 -10
- package/src/mutation/MutationRequestAuthorizationGuest.js +12 -15
- package/src/mutation/MutationRequestTokens.js +11 -14
- package/src/mutation/MutationTransferTokens.js +11 -14
- package/src/mutation/MutationWithdrawBufferToken.js +7 -10
- package/src/query/Query.js +62 -36
- package/src/query/QueryActiveSession.js +11 -13
- package/src/query/QueryAtom.js +75 -76
- package/src/query/QueryBalance.js +11 -12
- package/src/query/QueryBatch.js +17 -14
- package/src/query/QueryBatchHistory.js +16 -13
- package/src/query/QueryContinuId.js +13 -10
- package/src/query/QueryMetaType.js +45 -57
- package/src/query/QueryMetaTypeViaAtom.js +49 -57
- package/src/query/QueryPolicy.js +11 -12
- package/src/query/QueryToken.js +11 -13
- package/src/query/QueryUserActivity.js +11 -13
- package/src/query/QueryWalletBundle.js +15 -47
- package/src/query/QueryWalletList.js +15 -16
- package/src/response/Response.js +29 -34
- package/src/response/ResponseActiveSession.js +6 -6
- package/src/response/ResponseAtom.js +29 -30
- package/src/response/ResponseAuthorizationGuest.js +17 -18
- package/src/response/ResponseBalance.js +12 -13
- package/src/response/ResponseClaimShadowWallet.js +1 -1
- package/src/response/ResponseContinuId.js +21 -22
- package/src/response/ResponseCreateIdentifier.js +1 -1
- package/src/response/ResponseCreateMeta.js +1 -1
- package/src/response/ResponseCreateRule.js +1 -1
- package/src/response/ResponseCreateToken.js +1 -1
- package/src/response/ResponseCreateWallet.js +1 -1
- package/src/response/ResponseLinkIdentifier.js +9 -10
- package/src/response/ResponseMetaBatch.js +6 -8
- package/src/response/ResponseMetaType.js +19 -20
- package/src/response/ResponseMetaTypeViaAtom.js +19 -19
- package/src/response/ResponsePolicy.js +14 -15
- package/src/response/ResponseProposeMolecule.js +27 -30
- package/src/response/ResponseQueryActiveSession.js +20 -23
- package/src/response/ResponseQueryUserActivity.js +11 -12
- package/src/response/ResponseRequestAuthorization.js +11 -16
- package/src/response/ResponseRequestAuthorizationGuest.js +18 -21
- package/src/response/ResponseRequestTokens.js +1 -1
- package/src/response/ResponseTransferTokens.js +8 -9
- package/src/response/ResponseWalletBundle.js +16 -17
- package/src/response/ResponseWalletList.js +44 -47
- package/src/subscribe/ActiveSessionSubscribe.js +5 -6
- package/src/subscribe/ActiveWalletSubscribe.js +5 -6
- package/src/subscribe/CreateMoleculeSubscribe.js +5 -5
- package/src/subscribe/Subscribe.js +26 -26
- package/src/subscribe/WalletStatusSubscribe.js +5 -6
- package/src/versions/HashAtom.js +78 -0
- package/src/versions/Version4.js +34 -0
- package/src/versions/index.js +5 -0
- package/dist/client.umd.js +0 -453
- package/src/httpClient/ApolloClient.js +0 -245
- package/src/libraries/ApolloLink/CipherLink.js +0 -117
- package/src/libraries/ApolloLink/Client.js +0 -231
- package/src/libraries/ApolloLink/PusherLink.js +0 -234
- package/src/libraries/ApolloLink/handler.js +0 -106
- package/src/libraries/Base58.js +0 -71
- package/src/libraries/Base64.js +0 -40
- package/src/libraries/BaseX.js +0 -91
- package/src/libraries/Soda.js +0 -93
- package/src/query/QueryMetaInstance.js +0 -99
- package/src/test/Test.js +0 -670
- package/src/test/TestTokenUnit.js +0 -340
package/src/Molecule.js
CHANGED
|
@@ -45,63 +45,81 @@ Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
|
|
|
45
45
|
|
|
46
46
|
License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
|
|
47
47
|
*/
|
|
48
|
-
import Atom from './Atom'
|
|
49
|
-
import AtomMeta from './AtomMeta'
|
|
50
|
-
import Wallet from './Wallet'
|
|
51
|
-
import
|
|
48
|
+
import Atom from './Atom'
|
|
49
|
+
import AtomMeta from './AtomMeta'
|
|
50
|
+
import Wallet from './Wallet'
|
|
51
|
+
import JsSHA from 'jssha'
|
|
52
52
|
import {
|
|
53
53
|
chunkSubstr,
|
|
54
54
|
hexToBase64
|
|
55
|
-
} from './libraries/strings'
|
|
56
|
-
import CheckMolecule from './libraries/CheckMolecule'
|
|
55
|
+
} from './libraries/strings'
|
|
56
|
+
import CheckMolecule from './libraries/CheckMolecule'
|
|
57
57
|
import {
|
|
58
58
|
generateBatchId,
|
|
59
59
|
generateBundleHash
|
|
60
|
-
} from './libraries/crypto'
|
|
61
|
-
import { deepCloning } from './libraries/array'
|
|
62
|
-
import Dot from './libraries/Dot'
|
|
63
|
-
import Rule from './instance/Rules/Rule'
|
|
64
|
-
import AtomsMissingException from './exception/AtomsMissingException'
|
|
65
|
-
import BalanceInsufficientException from './exception/BalanceInsufficientException'
|
|
66
|
-
import NegativeAmountException from './exception/NegativeAmountException'
|
|
67
|
-
import SignatureMalformedException from './exception/SignatureMalformedException'
|
|
60
|
+
} from './libraries/crypto'
|
|
61
|
+
import { deepCloning } from './libraries/array'
|
|
62
|
+
import Dot from './libraries/Dot'
|
|
63
|
+
import Rule from './instance/Rules/Rule'
|
|
64
|
+
import AtomsMissingException from './exception/AtomsMissingException'
|
|
65
|
+
import BalanceInsufficientException from './exception/BalanceInsufficientException'
|
|
66
|
+
import NegativeAmountException from './exception/NegativeAmountException'
|
|
67
|
+
import SignatureMalformedException from './exception/SignatureMalformedException'
|
|
68
|
+
import versions from './versions/index'
|
|
68
69
|
|
|
69
70
|
/**
|
|
70
71
|
* Molecule class used for committing changes to the ledger
|
|
71
72
|
*/
|
|
72
73
|
export default class Molecule {
|
|
73
|
-
|
|
74
74
|
/**
|
|
75
75
|
* Class constructor
|
|
76
76
|
*
|
|
77
77
|
* @param {string|null} secret
|
|
78
|
+
* @param {string|null} bundle
|
|
78
79
|
* @param {Wallet|null} sourceWallet
|
|
79
80
|
* @param {Wallet|null} remainderWallet
|
|
80
81
|
* @param {string|null} cellSlug
|
|
82
|
+
* @param {string|number|null} version
|
|
81
83
|
*/
|
|
82
|
-
constructor (
|
|
84
|
+
constructor ({
|
|
83
85
|
secret = null,
|
|
86
|
+
bundle = null,
|
|
84
87
|
sourceWallet = null,
|
|
85
88
|
remainderWallet = null,
|
|
86
|
-
cellSlug = null
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
this.
|
|
90
|
-
this.
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
89
|
+
cellSlug = null,
|
|
90
|
+
version = null
|
|
91
|
+
}) {
|
|
92
|
+
this.status = null
|
|
93
|
+
this.molecularHash = null
|
|
94
|
+
this.createdAt = String(+new Date())
|
|
95
|
+
this.cellSlugOrigin = this.cellSlug = cellSlug
|
|
96
|
+
this.secret = secret
|
|
97
|
+
this.bundle = bundle
|
|
98
|
+
this.sourceWallet = sourceWallet
|
|
99
|
+
this.atoms = []
|
|
100
|
+
if (version !== null && Object.prototype.hasOwnProperty.call(versions, version)) {
|
|
101
|
+
this.version = String(version)
|
|
102
|
+
}
|
|
93
103
|
|
|
94
104
|
// Set the remainder wallet for this transaction
|
|
95
|
-
if (
|
|
96
|
-
this.remainderWallet = remainderWallet || Wallet.create(
|
|
97
|
-
|
|
105
|
+
if (remainderWallet || sourceWallet) {
|
|
106
|
+
this.remainderWallet = remainderWallet || Wallet.create({
|
|
107
|
+
secret,
|
|
108
|
+
bundle,
|
|
98
109
|
token: sourceWallet.token,
|
|
99
110
|
batchId: sourceWallet.batchId,
|
|
100
111
|
characters: sourceWallet.characters
|
|
101
|
-
}
|
|
112
|
+
})
|
|
102
113
|
}
|
|
114
|
+
}
|
|
103
115
|
|
|
104
|
-
|
|
116
|
+
/**
|
|
117
|
+
* Returns the cell slug delimiter
|
|
118
|
+
*
|
|
119
|
+
* @return {string}
|
|
120
|
+
*/
|
|
121
|
+
get cellSlugDelimiter () {
|
|
122
|
+
return '.'
|
|
105
123
|
}
|
|
106
124
|
|
|
107
125
|
/**
|
|
@@ -111,30 +129,147 @@ export default class Molecule {
|
|
|
111
129
|
* @param {array} atoms
|
|
112
130
|
* @returns {*[]}
|
|
113
131
|
*/
|
|
114
|
-
static isotopeFilter (
|
|
115
|
-
if (
|
|
116
|
-
isotopes = [
|
|
132
|
+
static isotopeFilter (isotopes, atoms) {
|
|
133
|
+
if (!Array.isArray(isotopes)) {
|
|
134
|
+
isotopes = [isotopes]
|
|
117
135
|
}
|
|
118
|
-
return atoms.filter(
|
|
136
|
+
return atoms.filter(atom => isotopes.includes(atom.isotope))
|
|
119
137
|
}
|
|
120
138
|
|
|
121
139
|
/**
|
|
140
|
+
* Generates the next atomic index
|
|
122
141
|
*
|
|
123
|
-
* @param
|
|
124
|
-
* @
|
|
142
|
+
* @param {array} atoms
|
|
143
|
+
* @return {number}
|
|
125
144
|
*/
|
|
126
|
-
|
|
127
|
-
return
|
|
145
|
+
static generateNextAtomIndex (atoms) {
|
|
146
|
+
return atoms.length
|
|
128
147
|
}
|
|
129
148
|
|
|
130
149
|
/**
|
|
131
|
-
*
|
|
150
|
+
* Converts a JSON object into a Molecule Structure instance
|
|
132
151
|
*
|
|
133
|
-
* @param {
|
|
134
|
-
* @return {
|
|
152
|
+
* @param {string} json
|
|
153
|
+
* @return {object}
|
|
154
|
+
* @throws {AtomsMissingException}
|
|
135
155
|
*/
|
|
136
|
-
static
|
|
137
|
-
|
|
156
|
+
static jsonToObject (json) {
|
|
157
|
+
const target = Object.assign(new Molecule({}), JSON.parse(json))
|
|
158
|
+
const properties = Object.keys(new Molecule({}))
|
|
159
|
+
|
|
160
|
+
if (!Array.isArray(target.atoms)) {
|
|
161
|
+
throw new AtomsMissingException()
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
for (const index in Object.keys(target.atoms)) {
|
|
165
|
+
target.atoms[index] = Atom.jsonToObject(JSON.stringify(target.atoms[index]))
|
|
166
|
+
|
|
167
|
+
for (const property of ['position', 'walletAddress', 'isotope']) {
|
|
168
|
+
if (target.atoms[index].isotope.toLowerCase() !== 'r' && (typeof target.atoms[index][property] === 'undefined' || target.atoms[index][property] === null)) {
|
|
169
|
+
throw new AtomsMissingException('MolecularStructure::jsonToObject() - Required Atom properties are missing!')
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
for (const property in target) {
|
|
175
|
+
if (Object.prototype.hasOwnProperty.call(target, property) && !properties.includes(property)) {
|
|
176
|
+
delete target[property]
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
target.atoms = Atom.sortAtoms(target.atoms)
|
|
181
|
+
|
|
182
|
+
return target
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Accept a string of letters and numbers, and outputs a collection of decimals representing each
|
|
187
|
+
* character according to a pre-defined dictionary. Input string would typically be 64-character
|
|
188
|
+
* hexadecimal string featuring numbers from 0 to 9 and characters from a to f - a total of 15
|
|
189
|
+
* unique symbols. To ensure that string has an even number of symbols, convert it to Base 17
|
|
190
|
+
* (adding G as a possible symbol). Map each symbol to integer values as follows:
|
|
191
|
+
* 0 1 2 3 4 5 6 7 8 9 a b c d e f g
|
|
192
|
+
* -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8
|
|
193
|
+
*
|
|
194
|
+
* @param {string} hash
|
|
195
|
+
* @return {array}
|
|
196
|
+
*/
|
|
197
|
+
static enumerate (hash) {
|
|
198
|
+
const mapped = {
|
|
199
|
+
0: -8,
|
|
200
|
+
1: -7,
|
|
201
|
+
2: -6,
|
|
202
|
+
3: -5,
|
|
203
|
+
4: -4,
|
|
204
|
+
5: -3,
|
|
205
|
+
6: -2,
|
|
206
|
+
7: -1,
|
|
207
|
+
8: 0,
|
|
208
|
+
9: 1,
|
|
209
|
+
a: 2,
|
|
210
|
+
b: 3,
|
|
211
|
+
c: 4,
|
|
212
|
+
d: 5,
|
|
213
|
+
e: 6,
|
|
214
|
+
f: 7,
|
|
215
|
+
g: 8
|
|
216
|
+
}
|
|
217
|
+
const target = []
|
|
218
|
+
const hashList = hash.toLowerCase().split('')
|
|
219
|
+
|
|
220
|
+
for (let index = 0, len = hashList.length; index < len; ++index) {
|
|
221
|
+
const symbol = hashList[index]
|
|
222
|
+
|
|
223
|
+
if (typeof mapped[symbol] !== 'undefined') {
|
|
224
|
+
target[index] = mapped[symbol]
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return target
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Normalize enumerated string to ensure that the total sum of all symbols is exactly zero. This
|
|
233
|
+
* ensures that exactly 50% of the WOTS+ key is leaked with each usage, ensuring predictable key
|
|
234
|
+
* safety:
|
|
235
|
+
* The sum of each symbol within Hm shall be presented by m
|
|
236
|
+
* While m0 iterate across that set’s integers as Im:
|
|
237
|
+
* If m0 and Im>-8 , let Im=Im-1
|
|
238
|
+
* If m<0 and Im<8 , let Im=Im+1
|
|
239
|
+
* If m=0, stop the iteration
|
|
240
|
+
*
|
|
241
|
+
* @param {array} mappedHashArray
|
|
242
|
+
* @return {array}
|
|
243
|
+
*/
|
|
244
|
+
static normalize (mappedHashArray) {
|
|
245
|
+
let total = mappedHashArray.reduce((total, num) => total + num)
|
|
246
|
+
|
|
247
|
+
const totalCondition = total < 0
|
|
248
|
+
|
|
249
|
+
while (total < 0 || total > 0) {
|
|
250
|
+
for (const index of Object.keys(mappedHashArray)) {
|
|
251
|
+
const condition = totalCondition ? mappedHashArray[index] < 8 : mappedHashArray[index] > -8
|
|
252
|
+
|
|
253
|
+
if (condition) {
|
|
254
|
+
const process = totalCondition ? [++mappedHashArray[index], ++total] : [--mappedHashArray[index], --total]
|
|
255
|
+
|
|
256
|
+
if (total === 0) {
|
|
257
|
+
break
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return mappedHashArray
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
*
|
|
268
|
+
* @param isotopes
|
|
269
|
+
* @returns {*[]}
|
|
270
|
+
*/
|
|
271
|
+
getIsotopes (isotopes) {
|
|
272
|
+
return Molecule.isotopeFilter(isotopes, this.atoms)
|
|
138
273
|
}
|
|
139
274
|
|
|
140
275
|
/**
|
|
@@ -143,7 +278,7 @@ export default class Molecule {
|
|
|
143
278
|
* @return {number}
|
|
144
279
|
*/
|
|
145
280
|
generateIndex () {
|
|
146
|
-
return Molecule.generateNextAtomIndex(
|
|
281
|
+
return Molecule.generateNextAtomIndex(this.atoms)
|
|
147
282
|
}
|
|
148
283
|
|
|
149
284
|
/**
|
|
@@ -151,9 +286,9 @@ export default class Molecule {
|
|
|
151
286
|
*
|
|
152
287
|
* @param {Molecule} molecule
|
|
153
288
|
*/
|
|
154
|
-
fill (
|
|
155
|
-
for (
|
|
156
|
-
this[
|
|
289
|
+
fill (molecule) {
|
|
290
|
+
for (const key in Object.keys(molecule)) {
|
|
291
|
+
this[key] = molecule[key]
|
|
157
292
|
}
|
|
158
293
|
}
|
|
159
294
|
|
|
@@ -162,37 +297,36 @@ export default class Molecule {
|
|
|
162
297
|
* @param {Atom} atom
|
|
163
298
|
* @returns {Molecule}
|
|
164
299
|
*/
|
|
165
|
-
addAtom (
|
|
166
|
-
|
|
300
|
+
addAtom (atom) {
|
|
167
301
|
// Reset the molecular hash
|
|
168
|
-
this.molecularHash = null
|
|
302
|
+
this.molecularHash = null
|
|
169
303
|
|
|
170
304
|
// Set atom's index
|
|
171
|
-
atom.index = this.generateIndex()
|
|
305
|
+
atom.index = this.generateIndex()
|
|
306
|
+
atom.version = this.version
|
|
172
307
|
|
|
173
308
|
// Add atom
|
|
174
|
-
this.atoms.push(
|
|
309
|
+
this.atoms.push(atom)
|
|
175
310
|
|
|
176
311
|
// Sort atoms
|
|
177
|
-
this.atoms = Atom.sortAtoms(
|
|
312
|
+
this.atoms = Atom.sortAtoms(this.atoms)
|
|
178
313
|
|
|
179
|
-
return this
|
|
314
|
+
return this
|
|
180
315
|
}
|
|
181
316
|
|
|
182
|
-
|
|
183
317
|
/**
|
|
184
318
|
* Add user remainder atom for ContinuID
|
|
185
319
|
*
|
|
186
320
|
* @return {Molecule}
|
|
187
321
|
*/
|
|
188
322
|
addContinuIdAtom () {
|
|
189
|
-
this.addAtom(
|
|
323
|
+
this.addAtom(Atom.create({
|
|
190
324
|
isotope: 'I',
|
|
191
325
|
wallet: this.remainderWallet,
|
|
192
326
|
metaType: 'walletBundle',
|
|
193
327
|
metaId: this.remainderWallet.bundle
|
|
194
|
-
}
|
|
195
|
-
return this
|
|
328
|
+
}))
|
|
329
|
+
return this
|
|
196
330
|
}
|
|
197
331
|
|
|
198
332
|
/**
|
|
@@ -204,71 +338,74 @@ export default class Molecule {
|
|
|
204
338
|
*
|
|
205
339
|
* @return {Molecule}
|
|
206
340
|
*/
|
|
207
|
-
addPolicyAtom (
|
|
341
|
+
addPolicyAtom ({
|
|
208
342
|
metaType,
|
|
209
343
|
metaId,
|
|
210
344
|
meta = {},
|
|
211
345
|
policy = {}
|
|
212
|
-
}
|
|
213
|
-
|
|
346
|
+
}) {
|
|
214
347
|
// AtomMeta object initialization
|
|
215
|
-
|
|
216
|
-
atomMeta.addPolicy(
|
|
348
|
+
const atomMeta = new AtomMeta(meta)
|
|
349
|
+
atomMeta.addPolicy(policy)
|
|
350
|
+
|
|
351
|
+
const wallet = Wallet.create({
|
|
352
|
+
secret: this.secret,
|
|
353
|
+
bundle: this.sourceWallet.bundle,
|
|
354
|
+
token: 'USER'
|
|
355
|
+
})
|
|
217
356
|
|
|
218
|
-
this.addAtom(
|
|
357
|
+
this.addAtom(Atom.create({
|
|
358
|
+
wallet,
|
|
219
359
|
isotope: 'R',
|
|
220
360
|
metaType,
|
|
221
361
|
metaId,
|
|
222
362
|
meta: atomMeta
|
|
223
|
-
}
|
|
224
|
-
return this
|
|
363
|
+
}))
|
|
364
|
+
return this
|
|
225
365
|
}
|
|
226
366
|
|
|
227
|
-
|
|
228
367
|
/**
|
|
229
368
|
*
|
|
230
369
|
* @param tokenUnits
|
|
231
370
|
* @param recipientWallet
|
|
232
371
|
* @returns {Molecule}
|
|
233
372
|
*/
|
|
234
|
-
fuseToken (
|
|
235
|
-
|
|
373
|
+
fuseToken (tokenUnits, recipientWallet) {
|
|
236
374
|
// Calculate amount
|
|
237
|
-
|
|
375
|
+
const amount = tokenUnits.length
|
|
238
376
|
|
|
239
|
-
if (
|
|
240
|
-
throw new BalanceInsufficientException()
|
|
377
|
+
if ((this.sourceWallet.balance - amount) < 0) {
|
|
378
|
+
throw new BalanceInsufficientException()
|
|
241
379
|
}
|
|
242
380
|
|
|
243
381
|
// Initializing a new Atom to remove tokens from source
|
|
244
|
-
this.addAtom(
|
|
382
|
+
this.addAtom(Atom.create({
|
|
245
383
|
isotope: 'V',
|
|
246
384
|
wallet: this.sourceWallet,
|
|
247
385
|
value: -amount
|
|
248
|
-
}
|
|
386
|
+
}))
|
|
249
387
|
|
|
250
388
|
// Add F isotope for fused tokens creation
|
|
251
|
-
this.addAtom(
|
|
389
|
+
this.addAtom(Atom.create({
|
|
252
390
|
isotope: 'F',
|
|
253
391
|
wallet: recipientWallet,
|
|
254
392
|
value: 1,
|
|
255
393
|
metaType: 'walletBundle',
|
|
256
394
|
metaId: recipientWallet.bundle
|
|
257
|
-
}
|
|
395
|
+
}))
|
|
258
396
|
|
|
259
397
|
// Initializing a new Atom to remove tokens from source
|
|
260
|
-
this.addAtom(
|
|
398
|
+
this.addAtom(Atom.create({
|
|
261
399
|
isotope: 'V',
|
|
262
400
|
wallet: this.remainderWallet,
|
|
263
401
|
value: this.sourceWallet.balance - amount,
|
|
264
402
|
metaType: 'walletBundle',
|
|
265
403
|
metaId: this.remainderWallet.bundle
|
|
266
|
-
}
|
|
404
|
+
}))
|
|
267
405
|
|
|
268
|
-
return this
|
|
406
|
+
return this
|
|
269
407
|
}
|
|
270
408
|
|
|
271
|
-
|
|
272
409
|
/**
|
|
273
410
|
* Burns some amount of tokens from a wallet
|
|
274
411
|
*
|
|
@@ -276,38 +413,34 @@ export default class Molecule {
|
|
|
276
413
|
* @param {string|null} walletBundle
|
|
277
414
|
* @return {Molecule}
|
|
278
415
|
*/
|
|
279
|
-
burnToken (
|
|
416
|
+
burnToken ({
|
|
280
417
|
amount,
|
|
281
418
|
walletBundle = null
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
throw new NegativeAmountException( 'Molecule::burnToken() - Amount to burn must be positive!' );
|
|
419
|
+
}) {
|
|
420
|
+
if (amount < 0.0) {
|
|
421
|
+
throw new NegativeAmountException('Molecule::burnToken() - Amount to burn must be positive!')
|
|
286
422
|
}
|
|
287
423
|
|
|
288
|
-
if (
|
|
289
|
-
throw new BalanceInsufficientException()
|
|
424
|
+
if ((this.sourceWallet.balance - amount) < 0) {
|
|
425
|
+
throw new BalanceInsufficientException()
|
|
290
426
|
}
|
|
291
427
|
|
|
292
|
-
this.
|
|
293
|
-
|
|
294
|
-
this.addAtom( Atom.create( {
|
|
428
|
+
this.addAtom(Atom.create({
|
|
295
429
|
isotope: 'V',
|
|
296
430
|
wallet: this.sourceWallet,
|
|
297
431
|
value: -amount
|
|
298
|
-
}
|
|
299
|
-
this.addAtom(
|
|
432
|
+
}))
|
|
433
|
+
this.addAtom(Atom.create({
|
|
300
434
|
isotope: 'V',
|
|
301
435
|
wallet: this.remainderWallet,
|
|
302
436
|
value: this.sourceWallet.balance - amount,
|
|
303
437
|
metaType: 'walletBundle',
|
|
304
438
|
metaId: this.remainderWallet.bundle
|
|
305
|
-
}
|
|
439
|
+
}))
|
|
306
440
|
|
|
307
|
-
return this
|
|
441
|
+
return this
|
|
308
442
|
}
|
|
309
443
|
|
|
310
|
-
|
|
311
444
|
/*
|
|
312
445
|
* Replenishes non-finite token supplies
|
|
313
446
|
*
|
|
@@ -316,57 +449,51 @@ export default class Molecule {
|
|
|
316
449
|
* @param {array|object} metas
|
|
317
450
|
* @return {Molecule}
|
|
318
451
|
*/
|
|
319
|
-
replenishToken (
|
|
452
|
+
replenishToken ({
|
|
320
453
|
amount,
|
|
321
454
|
units = []
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
throw new NegativeAmountException( 'Molecule::replenishToken() - Amount to replenish must be positive!' );
|
|
455
|
+
}) {
|
|
456
|
+
if (amount < 0) {
|
|
457
|
+
throw new NegativeAmountException('Molecule::replenishToken() - Amount to replenish must be positive!')
|
|
326
458
|
}
|
|
327
459
|
|
|
328
460
|
// Special code for the token unit logic
|
|
329
|
-
if (
|
|
330
|
-
|
|
461
|
+
if (units.length) {
|
|
331
462
|
// Prepare token units to formatted style
|
|
332
|
-
units = Wallet.getTokenUnits(
|
|
463
|
+
units = Wallet.getTokenUnits(units)
|
|
333
464
|
|
|
334
465
|
// Merge token units with source wallet & new items
|
|
335
|
-
this.remainderWallet.tokenUnits = this.sourceWallet.tokenUnits
|
|
336
|
-
for (
|
|
337
|
-
this.remainderWallet.tokenUnits.push(
|
|
466
|
+
this.remainderWallet.tokenUnits = this.sourceWallet.tokenUnits
|
|
467
|
+
for (const unit of units) {
|
|
468
|
+
this.remainderWallet.tokenUnits.push(unit)
|
|
338
469
|
}
|
|
339
|
-
this.remainderWallet.balance = this.remainderWallet.tokenUnits.length
|
|
470
|
+
this.remainderWallet.balance = this.remainderWallet.tokenUnits.length
|
|
340
471
|
|
|
341
472
|
// Override first atom's token units to replenish values
|
|
342
|
-
this.sourceWallet.tokenUnits = units
|
|
343
|
-
this.sourceWallet.balance = this.sourceWallet.tokenUnits.length
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
this.remainderWallet.balance = this.sourceWallet.balance + amount;
|
|
349
|
-
this.sourceWallet.balance = amount;
|
|
473
|
+
this.sourceWallet.tokenUnits = units
|
|
474
|
+
this.sourceWallet.balance = this.sourceWallet.tokenUnits.length
|
|
475
|
+
} else {
|
|
476
|
+
// Update wallet's balances
|
|
477
|
+
this.remainderWallet.balance = this.sourceWallet.balance + amount
|
|
478
|
+
this.sourceWallet.balance = amount
|
|
350
479
|
}
|
|
351
480
|
|
|
352
|
-
this.molecularHash = null;
|
|
353
|
-
|
|
354
481
|
// Initializing a new Atom to remove tokens from source
|
|
355
|
-
this.addAtom(
|
|
482
|
+
this.addAtom(Atom.create({
|
|
356
483
|
isotope: 'V',
|
|
357
484
|
wallet: this.sourceWallet,
|
|
358
485
|
value: this.sourceWallet.balance
|
|
359
|
-
}
|
|
486
|
+
}))
|
|
360
487
|
|
|
361
|
-
this.addAtom(
|
|
488
|
+
this.addAtom(Atom.create({
|
|
362
489
|
isotope: 'V',
|
|
363
490
|
wallet: this.remainderWallet,
|
|
364
491
|
value: this.remainderWallet.balance,
|
|
365
492
|
metaType: 'walletBundle',
|
|
366
493
|
metaId: this.remainderWallet.bundle
|
|
367
|
-
}
|
|
494
|
+
}))
|
|
368
495
|
|
|
369
|
-
return this
|
|
496
|
+
return this
|
|
370
497
|
}
|
|
371
498
|
|
|
372
499
|
/**
|
|
@@ -377,92 +504,87 @@ export default class Molecule {
|
|
|
377
504
|
* @param {number} amount
|
|
378
505
|
* @return {Molecule}
|
|
379
506
|
*/
|
|
380
|
-
initValue (
|
|
507
|
+
initValue ({
|
|
381
508
|
recipientWallet,
|
|
382
509
|
amount
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
throw new BalanceInsufficientException();
|
|
510
|
+
}) {
|
|
511
|
+
if (this.sourceWallet.balance - amount < 0) {
|
|
512
|
+
throw new BalanceInsufficientException()
|
|
387
513
|
}
|
|
388
514
|
|
|
389
|
-
this.molecularHash = null;
|
|
390
|
-
|
|
391
515
|
// Initializing a new Atom to remove tokens from source
|
|
392
|
-
this.addAtom(
|
|
516
|
+
this.addAtom(Atom.create({
|
|
393
517
|
isotope: 'V',
|
|
394
518
|
wallet: this.sourceWallet,
|
|
395
519
|
value: -amount
|
|
396
|
-
}
|
|
520
|
+
}))
|
|
397
521
|
// Initializing a new Atom to add tokens to recipient
|
|
398
|
-
this.addAtom(
|
|
522
|
+
this.addAtom(Atom.create({
|
|
399
523
|
isotope: 'V',
|
|
400
524
|
wallet: recipientWallet,
|
|
401
525
|
value: amount,
|
|
402
526
|
metaType: 'walletBundle',
|
|
403
527
|
metaId: recipientWallet.bundle
|
|
404
|
-
}
|
|
528
|
+
}))
|
|
405
529
|
// Ininitlizing a remainder atom
|
|
406
|
-
this.addAtom(
|
|
530
|
+
this.addAtom(Atom.create({
|
|
407
531
|
isotope: 'V',
|
|
408
532
|
wallet: this.remainderWallet,
|
|
409
533
|
value: this.sourceWallet.balance - amount,
|
|
410
534
|
metaType: 'walletBundle',
|
|
411
535
|
metaId: this.remainderWallet.bundle
|
|
412
|
-
}
|
|
536
|
+
}))
|
|
413
537
|
|
|
414
|
-
return this
|
|
538
|
+
return this
|
|
415
539
|
}
|
|
416
540
|
|
|
417
|
-
|
|
418
541
|
/**
|
|
419
542
|
*
|
|
420
543
|
* @param amount
|
|
421
544
|
* @param tradeRates
|
|
422
545
|
*/
|
|
423
|
-
initDepositBuffer (
|
|
546
|
+
initDepositBuffer ({
|
|
424
547
|
amount,
|
|
425
548
|
tradeRates
|
|
426
|
-
}
|
|
427
|
-
if (
|
|
428
|
-
throw new BalanceInsufficientException()
|
|
549
|
+
}) {
|
|
550
|
+
if (this.sourceWallet.balance - amount < 0) {
|
|
551
|
+
throw new BalanceInsufficientException()
|
|
429
552
|
}
|
|
430
553
|
|
|
431
554
|
// Create a buffer wallet
|
|
432
|
-
|
|
433
|
-
|
|
555
|
+
const bufferWallet = Wallet.create({
|
|
556
|
+
secret: this.secret,
|
|
557
|
+
bundle: this.bundle,
|
|
434
558
|
token: this.sourceWallet.token,
|
|
435
559
|
batchId: this.sourceWallet.batchId
|
|
436
|
-
}
|
|
437
|
-
bufferWallet.tradeRates = tradeRates
|
|
438
|
-
|
|
439
|
-
this.molecularHash = null;
|
|
560
|
+
})
|
|
561
|
+
bufferWallet.tradeRates = tradeRates
|
|
440
562
|
|
|
441
563
|
// Initializing a new Atom to remove tokens from source
|
|
442
|
-
this.addAtom(
|
|
564
|
+
this.addAtom(Atom.create({
|
|
443
565
|
isotope: 'V',
|
|
444
566
|
wallet: this.sourceWallet,
|
|
445
567
|
value: -amount
|
|
446
|
-
}
|
|
568
|
+
}))
|
|
447
569
|
|
|
448
570
|
// Initializing a new Atom to add tokens to recipient
|
|
449
|
-
this.addAtom(
|
|
571
|
+
this.addAtom(Atom.create({
|
|
450
572
|
isotope: 'B',
|
|
451
573
|
wallet: bufferWallet,
|
|
452
574
|
value: amount,
|
|
453
575
|
metaType: 'walletBundle',
|
|
454
576
|
metaId: this.sourceWallet.bundle
|
|
455
|
-
}
|
|
577
|
+
}))
|
|
456
578
|
|
|
457
|
-
this.addAtom(
|
|
579
|
+
this.addAtom(Atom.create({
|
|
458
580
|
isotope: 'V',
|
|
459
581
|
wallet: this.remainderWallet,
|
|
460
582
|
value: this.sourceWallet.balance - amount,
|
|
461
583
|
metaType: 'walletBundle',
|
|
462
584
|
metaId: this.sourceWallet.bundle
|
|
463
|
-
}
|
|
585
|
+
}))
|
|
464
586
|
|
|
465
|
-
return this
|
|
587
|
+
return this
|
|
466
588
|
}
|
|
467
589
|
|
|
468
590
|
/**
|
|
@@ -471,89 +593,56 @@ export default class Molecule {
|
|
|
471
593
|
* @param {Wallet|{}} signingWallet
|
|
472
594
|
* @returns {Molecule}
|
|
473
595
|
*/
|
|
474
|
-
initWithdrawBuffer (
|
|
596
|
+
initWithdrawBuffer ({
|
|
475
597
|
recipients,
|
|
476
598
|
signingWallet = null
|
|
477
|
-
}
|
|
478
|
-
|
|
599
|
+
}) {
|
|
479
600
|
// Calculate final amount from all recipients
|
|
480
|
-
let amount = 0
|
|
481
|
-
for (
|
|
482
|
-
amount += recipientAmount
|
|
601
|
+
let amount = 0
|
|
602
|
+
for (const [recipientBundle, recipientAmount] of Object.entries(recipients || {})) {
|
|
603
|
+
amount += recipientAmount
|
|
483
604
|
}
|
|
484
|
-
if (
|
|
485
|
-
throw new BalanceInsufficientException()
|
|
605
|
+
if (this.sourceWallet.balance - amount < 0) {
|
|
606
|
+
throw new BalanceInsufficientException()
|
|
486
607
|
}
|
|
487
608
|
|
|
488
609
|
// Set a metas signing position for molecule correct reconciliation
|
|
489
|
-
|
|
490
|
-
if (
|
|
491
|
-
firstAtomMeta.
|
|
610
|
+
const firstAtomMeta = new AtomMeta()
|
|
611
|
+
if (signingWallet) {
|
|
612
|
+
firstAtomMeta.setSigningWallet(signingWallet)
|
|
492
613
|
}
|
|
493
614
|
|
|
494
615
|
// Initializing a new Atom to remove tokens from source
|
|
495
|
-
this.addAtom(
|
|
616
|
+
this.addAtom(Atom.create({
|
|
496
617
|
isotope: 'B',
|
|
497
618
|
wallet: this.sourceWallet,
|
|
498
619
|
value: -amount,
|
|
499
620
|
meta: firstAtomMeta,
|
|
500
621
|
metaType: 'walletBundle',
|
|
501
622
|
metaId: this.sourceWallet.bundle
|
|
502
|
-
}
|
|
623
|
+
}))
|
|
503
624
|
|
|
504
625
|
// Initializing a new Atom to add tokens to recipient
|
|
505
|
-
for (
|
|
506
|
-
this.addAtom(
|
|
626
|
+
for (const [recipientBundle, recipientAmount] of Object.entries(recipients || {})) {
|
|
627
|
+
this.addAtom(new Atom({
|
|
507
628
|
isotope: 'V',
|
|
508
629
|
token: this.sourceWallet.token,
|
|
509
630
|
value: recipientAmount,
|
|
510
|
-
batchId: this.sourceWallet.batchId ? generateBatchId(
|
|
631
|
+
batchId: this.sourceWallet.batchId ? generateBatchId({}) : null,
|
|
511
632
|
metaType: 'walletBundle',
|
|
512
633
|
metaId: recipientBundle
|
|
513
|
-
}
|
|
634
|
+
}))
|
|
514
635
|
}
|
|
515
636
|
|
|
516
|
-
this.addAtom(
|
|
637
|
+
this.addAtom(Atom.create({
|
|
517
638
|
isotope: 'B',
|
|
518
639
|
wallet: this.remainderWallet,
|
|
519
640
|
value: this.sourceWallet.balance - amount,
|
|
520
641
|
metaType: 'walletBundle',
|
|
521
642
|
metaId: this.remainderWallet.bundle
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
return this;
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
/**
|
|
528
|
-
* Builds Atoms to define a new wallet on the ledger
|
|
529
|
-
*
|
|
530
|
-
* @param {Wallet} newWallet
|
|
531
|
-
* @return {Molecule}
|
|
532
|
-
*/
|
|
533
|
-
initWalletCreation ( newWallet ) {
|
|
534
|
-
|
|
535
|
-
this.molecularHash = null;
|
|
536
|
-
|
|
537
|
-
let meta = new AtomMeta( {
|
|
538
|
-
address: newWallet.address,
|
|
539
|
-
token: newWallet.token,
|
|
540
|
-
bundle: newWallet.bundle,
|
|
541
|
-
position: newWallet.position,
|
|
542
|
-
amount: 0,
|
|
543
|
-
batchId: newWallet.batchId
|
|
544
|
-
} );
|
|
545
|
-
|
|
546
|
-
this.addAtom( Atom.create( {
|
|
547
|
-
isotope: 'C',
|
|
548
|
-
wallet: this.sourceWallet,
|
|
549
|
-
metaType: 'wallet',
|
|
550
|
-
metaId: newWallet.address,
|
|
551
|
-
meta
|
|
552
|
-
} ) );
|
|
553
|
-
|
|
554
|
-
this.addContinuIdAtom();
|
|
643
|
+
}))
|
|
555
644
|
|
|
556
|
-
return this
|
|
645
|
+
return this
|
|
557
646
|
}
|
|
558
647
|
|
|
559
648
|
/**
|
|
@@ -564,36 +653,29 @@ export default class Molecule {
|
|
|
564
653
|
* @param {array|object} meta - additional fields to configure the token
|
|
565
654
|
* @return {Molecule}
|
|
566
655
|
*/
|
|
567
|
-
initTokenCreation (
|
|
656
|
+
initTokenCreation ({
|
|
568
657
|
recipientWallet,
|
|
569
658
|
amount,
|
|
570
659
|
meta
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
// Importing wallet fields into meta object
|
|
576
|
-
for ( const walletKey of [ 'walletAddress', 'walletPosition', 'walletPubkey', 'walletCharacters' ] ) {
|
|
577
|
-
if ( !meta[ walletKey ] ) {
|
|
578
|
-
meta[ walletKey ] = recipientWallet[ walletKey.toLowerCase().substring( 6 ) ];
|
|
579
|
-
}
|
|
580
|
-
}
|
|
660
|
+
}) {
|
|
661
|
+
const atomMeta = new AtomMeta(meta)
|
|
662
|
+
atomMeta.setMetaWallet(recipientWallet)
|
|
581
663
|
|
|
582
664
|
// The primary atom tells the ledger that a certain amount of the new token is being issued.
|
|
583
|
-
this.addAtom(
|
|
665
|
+
this.addAtom(Atom.create({
|
|
584
666
|
isotope: 'C',
|
|
585
667
|
wallet: this.sourceWallet,
|
|
586
668
|
value: amount,
|
|
587
669
|
metaType: 'token',
|
|
588
670
|
metaId: recipientWallet.token,
|
|
589
|
-
meta:
|
|
671
|
+
meta: atomMeta,
|
|
590
672
|
batchId: recipientWallet.batchId
|
|
591
|
-
}
|
|
673
|
+
}))
|
|
592
674
|
|
|
593
675
|
// User remainder atom
|
|
594
|
-
this.addContinuIdAtom()
|
|
676
|
+
this.addContinuIdAtom()
|
|
595
677
|
|
|
596
|
-
return this
|
|
678
|
+
return this
|
|
597
679
|
}
|
|
598
680
|
|
|
599
681
|
/**
|
|
@@ -604,74 +686,74 @@ export default class Molecule {
|
|
|
604
686
|
* @param {object} policy
|
|
605
687
|
* @return {Molecule}
|
|
606
688
|
*/
|
|
607
|
-
createRule (
|
|
689
|
+
createRule ({
|
|
608
690
|
metaType,
|
|
609
691
|
metaId,
|
|
610
692
|
rule,
|
|
611
693
|
policy = {}
|
|
612
|
-
}
|
|
613
|
-
const $rules = []
|
|
694
|
+
}) {
|
|
695
|
+
const $rules = []
|
|
614
696
|
|
|
615
|
-
for (
|
|
616
|
-
$rules.push(
|
|
697
|
+
for (const $rule of rule) {
|
|
698
|
+
$rules.push($rule instanceof Rule ? $rule : Rule.toObject($rule))
|
|
617
699
|
}
|
|
618
700
|
|
|
619
701
|
// Create atom meta with rules
|
|
620
|
-
|
|
621
|
-
rule: JSON.stringify(
|
|
622
|
-
}
|
|
702
|
+
const atomMeta = new AtomMeta({
|
|
703
|
+
rule: JSON.stringify($rules)
|
|
704
|
+
})
|
|
623
705
|
|
|
624
706
|
// Add policies to meta object
|
|
625
|
-
atomMeta.addPolicy(
|
|
707
|
+
atomMeta.addPolicy(policy)
|
|
626
708
|
|
|
627
|
-
this.addAtom(
|
|
709
|
+
this.addAtom(Atom.create({
|
|
628
710
|
isotope: 'R',
|
|
629
711
|
wallet: this.sourceWallet,
|
|
630
712
|
metaType,
|
|
631
713
|
metaId,
|
|
632
714
|
meta: atomMeta
|
|
633
|
-
}
|
|
715
|
+
}))
|
|
634
716
|
|
|
635
717
|
// User continuID atom
|
|
636
|
-
this.addContinuIdAtom()
|
|
718
|
+
this.addContinuIdAtom()
|
|
637
719
|
|
|
638
|
-
return this
|
|
720
|
+
return this
|
|
639
721
|
}
|
|
640
722
|
|
|
641
|
-
|
|
642
723
|
/**
|
|
643
|
-
*
|
|
724
|
+
* Builds Atoms to define a new wallet on the ledger
|
|
644
725
|
*
|
|
645
|
-
* @param
|
|
646
|
-
* @param
|
|
726
|
+
* @param {Wallet} wallet
|
|
727
|
+
* @param {AtomMeta|null} atomMeta
|
|
728
|
+
* @return {Molecule}
|
|
647
729
|
*/
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
let metas = {
|
|
655
|
-
tokenSlug: token,
|
|
656
|
-
walletAddress: wallet.address,
|
|
657
|
-
walletPosition: wallet.position,
|
|
658
|
-
pubkey: wallet.pubkey,
|
|
659
|
-
characters: wallet.characters,
|
|
660
|
-
batchId: wallet.batchId
|
|
661
|
-
};
|
|
662
|
-
|
|
663
|
-
this.addAtom( Atom.create( {
|
|
730
|
+
initWalletCreation (wallet, atomMeta = null) {
|
|
731
|
+
if (!atomMeta) {
|
|
732
|
+
atomMeta = new AtomMeta()
|
|
733
|
+
}
|
|
734
|
+
atomMeta.setMetaWallet(wallet)
|
|
735
|
+
const creationAtom = Atom.create({
|
|
664
736
|
isotope: 'C',
|
|
665
737
|
wallet: this.sourceWallet,
|
|
666
738
|
metaType: 'wallet',
|
|
667
739
|
metaId: wallet.address,
|
|
668
|
-
meta:
|
|
669
|
-
|
|
740
|
+
meta: atomMeta,
|
|
741
|
+
batchId: wallet.batchId
|
|
742
|
+
})
|
|
743
|
+
this.addAtom(creationAtom)
|
|
744
|
+
this.addContinuIdAtom()
|
|
670
745
|
|
|
671
|
-
|
|
672
|
-
|
|
746
|
+
return this
|
|
747
|
+
}
|
|
673
748
|
|
|
674
|
-
|
|
749
|
+
/**
|
|
750
|
+
* Init shadow wallet claim
|
|
751
|
+
*
|
|
752
|
+
* @param wallet
|
|
753
|
+
*/
|
|
754
|
+
initShadowWalletClaim (wallet) {
|
|
755
|
+
const atomMeta = (new AtomMeta()).setShadowWalletClaim(true)
|
|
756
|
+
return this.initWalletCreation(wallet, atomMeta)
|
|
675
757
|
}
|
|
676
758
|
|
|
677
759
|
/**
|
|
@@ -683,28 +765,27 @@ export default class Molecule {
|
|
|
683
765
|
*
|
|
684
766
|
* @return {Molecule}
|
|
685
767
|
*/
|
|
686
|
-
initIdentifierCreation (
|
|
768
|
+
initIdentifierCreation ({
|
|
687
769
|
type,
|
|
688
770
|
contact,
|
|
689
771
|
code
|
|
690
|
-
}
|
|
691
|
-
|
|
772
|
+
}) {
|
|
692
773
|
const meta = {
|
|
693
|
-
code
|
|
694
|
-
hash: generateBundleHash(
|
|
695
|
-
}
|
|
774
|
+
code,
|
|
775
|
+
hash: generateBundleHash(contact.trim(), 'Molecule::initIdentifierCreation')
|
|
776
|
+
}
|
|
696
777
|
|
|
697
|
-
this.addAtom(
|
|
778
|
+
this.addAtom(Atom.create({
|
|
698
779
|
isotope: 'C',
|
|
699
780
|
wallet: this.sourceWallet,
|
|
700
781
|
metaType: 'identifier',
|
|
701
782
|
metaId: type,
|
|
702
|
-
meta: new AtomMeta(
|
|
703
|
-
}
|
|
783
|
+
meta: new AtomMeta(meta)
|
|
784
|
+
}))
|
|
704
785
|
|
|
705
|
-
this.addContinuIdAtom()
|
|
786
|
+
this.addContinuIdAtom()
|
|
706
787
|
|
|
707
|
-
return this
|
|
788
|
+
return this
|
|
708
789
|
}
|
|
709
790
|
|
|
710
791
|
/**
|
|
@@ -716,33 +797,32 @@ export default class Molecule {
|
|
|
716
797
|
* @param {object} policy
|
|
717
798
|
* @return {Molecule}
|
|
718
799
|
*/
|
|
719
|
-
initMeta (
|
|
800
|
+
initMeta ({
|
|
720
801
|
meta,
|
|
721
802
|
metaType,
|
|
722
803
|
metaId,
|
|
723
804
|
policy
|
|
724
|
-
}
|
|
725
|
-
|
|
805
|
+
}) {
|
|
726
806
|
// Initializing a new Atom to hold our metadata
|
|
727
|
-
this.addAtom(
|
|
807
|
+
this.addAtom(Atom.create({
|
|
728
808
|
isotope: 'M',
|
|
729
809
|
wallet: this.sourceWallet,
|
|
730
810
|
metaType,
|
|
731
811
|
metaId,
|
|
732
|
-
meta: new AtomMeta(
|
|
733
|
-
}
|
|
812
|
+
meta: new AtomMeta(meta)
|
|
813
|
+
}))
|
|
734
814
|
|
|
735
|
-
this.addPolicyAtom(
|
|
815
|
+
this.addPolicyAtom({
|
|
736
816
|
metaType,
|
|
737
817
|
metaId,
|
|
738
818
|
meta,
|
|
739
819
|
policy
|
|
740
|
-
}
|
|
820
|
+
})
|
|
741
821
|
|
|
742
822
|
// User remainder atom
|
|
743
|
-
this.addContinuIdAtom()
|
|
823
|
+
this.addContinuIdAtom()
|
|
744
824
|
|
|
745
|
-
return this
|
|
825
|
+
return this
|
|
746
826
|
}
|
|
747
827
|
|
|
748
828
|
/**
|
|
@@ -757,31 +837,32 @@ export default class Molecule {
|
|
|
757
837
|
*
|
|
758
838
|
* @return {Molecule}
|
|
759
839
|
*/
|
|
760
|
-
initTokenRequest (
|
|
840
|
+
initTokenRequest ({
|
|
761
841
|
token,
|
|
762
842
|
amount,
|
|
763
843
|
metaType,
|
|
764
844
|
metaId,
|
|
765
845
|
meta = {},
|
|
766
846
|
batchId = null
|
|
767
|
-
}
|
|
847
|
+
}) {
|
|
848
|
+
meta.token = token
|
|
768
849
|
|
|
769
|
-
|
|
850
|
+
this.local = 1
|
|
770
851
|
|
|
771
|
-
this.addAtom(
|
|
852
|
+
this.addAtom(Atom.create({
|
|
772
853
|
isotope: 'T',
|
|
773
854
|
wallet: this.sourceWallet,
|
|
774
855
|
value: amount,
|
|
775
856
|
metaType,
|
|
776
857
|
metaId,
|
|
777
|
-
meta: new AtomMeta(
|
|
858
|
+
meta: new AtomMeta(meta),
|
|
778
859
|
batchId
|
|
779
|
-
}
|
|
860
|
+
}))
|
|
780
861
|
|
|
781
862
|
// User remainder atom
|
|
782
|
-
this.addContinuIdAtom()
|
|
863
|
+
this.addContinuIdAtom()
|
|
783
864
|
|
|
784
|
-
return this
|
|
865
|
+
return this
|
|
785
866
|
}
|
|
786
867
|
|
|
787
868
|
/**
|
|
@@ -791,171 +872,107 @@ export default class Molecule {
|
|
|
791
872
|
*
|
|
792
873
|
* @return {Molecule}
|
|
793
874
|
*/
|
|
794
|
-
initAuthorization (
|
|
795
|
-
|
|
796
|
-
this.addAtom( Atom.create( {
|
|
875
|
+
initAuthorization ({ meta }) {
|
|
876
|
+
this.addAtom(Atom.create({
|
|
797
877
|
isotope: 'U',
|
|
798
878
|
wallet: this.sourceWallet,
|
|
799
|
-
meta: new AtomMeta(
|
|
800
|
-
}
|
|
879
|
+
meta: new AtomMeta(meta)
|
|
880
|
+
}))
|
|
801
881
|
|
|
802
882
|
// User remainder atom
|
|
803
|
-
this.addContinuIdAtom()
|
|
883
|
+
this.addContinuIdAtom()
|
|
804
884
|
|
|
805
|
-
return this
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
* Clears the instance of the data, leads the instance to a state equivalent to that after new Molecule()
|
|
810
|
-
*
|
|
811
|
-
* @return {Molecule}
|
|
812
|
-
*/
|
|
813
|
-
clear () {
|
|
814
|
-
this.molecularHash = null;
|
|
815
|
-
this.bundle = null;
|
|
816
|
-
this.status = null;
|
|
817
|
-
this.createdAt = String( +new Date );
|
|
818
|
-
this.atoms = [];
|
|
819
|
-
|
|
820
|
-
return this;
|
|
885
|
+
return this
|
|
821
886
|
}
|
|
822
887
|
|
|
823
888
|
/**
|
|
824
889
|
* Creates a one-time signature for a molecule and breaks it up across multiple atoms within that
|
|
825
890
|
* molecule. Resulting 4096 byte (2048 character) string is the one-time signature, which is then compressed.
|
|
826
891
|
*
|
|
892
|
+
* @param {string|null} bundle
|
|
827
893
|
* @param {boolean} anonymous
|
|
828
894
|
* @param {boolean} compressed
|
|
829
895
|
* @return {string|null}
|
|
830
896
|
* @throws {AtomsMissingException}
|
|
831
897
|
*/
|
|
832
|
-
sign (
|
|
898
|
+
sign ({
|
|
899
|
+
bundle = null,
|
|
833
900
|
anonymous = false,
|
|
834
901
|
compressed = true
|
|
835
|
-
}
|
|
836
|
-
|
|
902
|
+
}) {
|
|
837
903
|
// Do we have atoms?
|
|
838
|
-
if (
|
|
839
|
-
throw new AtomsMissingException()
|
|
904
|
+
if (this.atoms.length === 0 || this.atoms.filter(atom => !(atom instanceof Atom)).length !== 0) {
|
|
905
|
+
throw new AtomsMissingException()
|
|
840
906
|
}
|
|
841
907
|
|
|
842
908
|
// Derive the user's bundle
|
|
843
|
-
if (
|
|
844
|
-
this.bundle = generateBundleHash(
|
|
909
|
+
if (!anonymous && !this.bundle) {
|
|
910
|
+
this.bundle = bundle || generateBundleHash(this.secret, 'Molecule::sign')
|
|
845
911
|
}
|
|
846
912
|
|
|
847
913
|
// Hash atoms to get molecular hash
|
|
848
|
-
this.molecularHash = Atom.hashAtoms(
|
|
914
|
+
this.molecularHash = Atom.hashAtoms({
|
|
849
915
|
atoms: this.atoms
|
|
850
|
-
}
|
|
916
|
+
})
|
|
851
917
|
|
|
852
918
|
// Signing atom
|
|
853
|
-
const signingAtom = this.atoms[
|
|
919
|
+
const signingAtom = this.atoms[0]
|
|
854
920
|
|
|
855
921
|
// Set signing position from the first atom
|
|
856
|
-
let signingPosition = signingAtom.position
|
|
922
|
+
let signingPosition = signingAtom.position
|
|
857
923
|
|
|
858
924
|
// Get signing wallet from first atom's metas
|
|
859
|
-
|
|
925
|
+
const signingWallet = Dot.get(signingAtom.aggregatedMeta(), 'signingWallet')
|
|
860
926
|
|
|
861
927
|
// Try to get custom signing position from the metas (local molecule with server secret)
|
|
862
|
-
if (
|
|
863
|
-
signingPosition = Dot.get(
|
|
928
|
+
if (signingWallet) {
|
|
929
|
+
signingPosition = Dot.get(JSON.parse(signingWallet), 'position')
|
|
864
930
|
}
|
|
865
931
|
|
|
866
932
|
// Signing position is required
|
|
867
|
-
if (
|
|
868
|
-
throw new SignatureMalformedException(
|
|
933
|
+
if (!signingPosition) {
|
|
934
|
+
throw new SignatureMalformedException('Signing wallet must have a position!')
|
|
869
935
|
}
|
|
870
936
|
|
|
871
937
|
// Generate the private signing key for this molecule
|
|
872
|
-
const key = Wallet.generateKey(
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
938
|
+
const key = Wallet.generateKey({
|
|
939
|
+
secret: this.secret,
|
|
940
|
+
token: signingAtom.token,
|
|
941
|
+
position: signingAtom.position
|
|
942
|
+
})
|
|
943
|
+
// Subdivide Kk into 16 segments of 256 bytes (128 characters) each
|
|
944
|
+
const keyChunks = chunkSubstr(key, 128)
|
|
945
|
+
// Convert Hm to numeric notation, and then normalize
|
|
946
|
+
const normalizedHash = this.normalizedHash()
|
|
881
947
|
|
|
882
948
|
// Building a one-time-signature
|
|
883
|
-
let signatureFragments = ''
|
|
949
|
+
let signatureFragments = ''
|
|
884
950
|
|
|
885
|
-
for (
|
|
951
|
+
for (const index in keyChunks) {
|
|
952
|
+
let workingChunk = keyChunks[index]
|
|
886
953
|
|
|
887
|
-
let
|
|
888
|
-
|
|
889
|
-
for ( let iterationCount = 0, condition = 8 - normalizedHash[ index ]; iterationCount < condition; iterationCount++ ) {
|
|
890
|
-
workingChunk = shake256.create( 512 ).update( workingChunk ).hex();
|
|
954
|
+
for (let iterationCount = 0, condition = 8 - normalizedHash[index]; iterationCount < condition; iterationCount++) {
|
|
955
|
+
workingChunk = (new JsSHA('SHAKE256', 'TEXT')).update(workingChunk).getHash('HEX', { outputLen: 512 })
|
|
891
956
|
}
|
|
892
|
-
signatureFragments += workingChunk
|
|
957
|
+
signatureFragments += workingChunk
|
|
893
958
|
}
|
|
894
959
|
|
|
895
960
|
// Compressing the OTS
|
|
896
|
-
if (
|
|
897
|
-
signatureFragments = hexToBase64(
|
|
961
|
+
if (compressed) {
|
|
962
|
+
signatureFragments = hexToBase64(signatureFragments)
|
|
898
963
|
}
|
|
899
964
|
|
|
900
965
|
// Chunking the signature across multiple atoms
|
|
901
|
-
const chunkedSignature = chunkSubstr(
|
|
966
|
+
const chunkedSignature = chunkSubstr(signatureFragments, Math.ceil(signatureFragments.length / this.atoms.length))
|
|
902
967
|
|
|
903
|
-
let lastPosition = null
|
|
968
|
+
let lastPosition = null
|
|
904
969
|
|
|
905
|
-
for (
|
|
906
|
-
this.atoms[
|
|
907
|
-
lastPosition = this.atoms[
|
|
970
|
+
for (let chunkCount = 0, condition = chunkedSignature.length; chunkCount < condition; chunkCount++) {
|
|
971
|
+
this.atoms[chunkCount].otsFragment = chunkedSignature[chunkCount]
|
|
972
|
+
lastPosition = this.atoms[chunkCount].position
|
|
908
973
|
}
|
|
909
974
|
|
|
910
|
-
return lastPosition
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
/**
|
|
914
|
-
* Converts a JSON object into a Molecule Structure instance
|
|
915
|
-
*
|
|
916
|
-
* @param {string} json
|
|
917
|
-
* @return {object}
|
|
918
|
-
* @throws {AtomsMissingException}
|
|
919
|
-
*/
|
|
920
|
-
static jsonToObject ( json ) {
|
|
921
|
-
const target = Object.assign( new Molecule( {} ), JSON.parse( json ) ),
|
|
922
|
-
properties = Object.keys( new Molecule( {} ) );
|
|
923
|
-
|
|
924
|
-
if ( !Array.isArray( target.atoms ) ) {
|
|
925
|
-
throw new AtomsMissingException();
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
for ( const index in Object.keys( target.atoms ) ) {
|
|
929
|
-
|
|
930
|
-
target.atoms[ index ] = Atom.jsonToObject( JSON.stringify( target.atoms[ index ] ) );
|
|
931
|
-
|
|
932
|
-
for ( const property of [ 'position', 'walletAddress', 'isotope' ] ) {
|
|
933
|
-
|
|
934
|
-
if ( typeof target.atoms[ index ][ property ] === 'undefined' || null === target.atoms[ index ][ property ] ) {
|
|
935
|
-
throw new AtomsMissingException( 'MolecularStructure::jsonToObject() - Required Atom properties are missing!' );
|
|
936
|
-
}
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
|
|
940
|
-
for ( const property in target ) {
|
|
941
|
-
|
|
942
|
-
if ( target.hasOwnProperty( property ) && !properties.includes( property ) ) {
|
|
943
|
-
delete target[ property ];
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
|
|
947
|
-
target.atoms = Atom.sortAtoms( target.atoms );
|
|
948
|
-
|
|
949
|
-
return target;
|
|
950
|
-
}
|
|
951
|
-
|
|
952
|
-
/**
|
|
953
|
-
* Returns the cell slug delimiter
|
|
954
|
-
*
|
|
955
|
-
* @return {string}
|
|
956
|
-
*/
|
|
957
|
-
get cellSlugDelimiter () {
|
|
958
|
-
return '.';
|
|
975
|
+
return lastPosition
|
|
959
976
|
}
|
|
960
977
|
|
|
961
978
|
/**
|
|
@@ -964,7 +981,7 @@ export default class Molecule {
|
|
|
964
981
|
* @return {string}
|
|
965
982
|
*/
|
|
966
983
|
cellSlugBase () {
|
|
967
|
-
return (
|
|
984
|
+
return (this.cellSlug || '').split(this.cellSlugDelimiter)[0]
|
|
968
985
|
}
|
|
969
986
|
|
|
970
987
|
/**
|
|
@@ -973,13 +990,13 @@ export default class Molecule {
|
|
|
973
990
|
* @return {object}
|
|
974
991
|
*/
|
|
975
992
|
toJSON () {
|
|
976
|
-
|
|
977
|
-
for (
|
|
978
|
-
if (
|
|
979
|
-
delete clone[
|
|
993
|
+
const clone = deepCloning(this)
|
|
994
|
+
for (const key of ['remainderWallet', 'secret', 'sourceWallet', 'cellSlugOrigin', 'version']) {
|
|
995
|
+
if (Object.prototype.hasOwnProperty.call(clone, key)) {
|
|
996
|
+
delete clone[key]
|
|
980
997
|
}
|
|
981
998
|
}
|
|
982
|
-
return clone
|
|
999
|
+
return clone
|
|
983
1000
|
}
|
|
984
1001
|
|
|
985
1002
|
/**
|
|
@@ -987,8 +1004,8 @@ export default class Molecule {
|
|
|
987
1004
|
*
|
|
988
1005
|
* @param senderWallet
|
|
989
1006
|
*/
|
|
990
|
-
check (
|
|
991
|
-
(
|
|
1007
|
+
check (senderWallet = null) {
|
|
1008
|
+
(new CheckMolecule(this)).verify(senderWallet)
|
|
992
1009
|
}
|
|
993
1010
|
|
|
994
1011
|
/**
|
|
@@ -997,94 +1014,6 @@ export default class Molecule {
|
|
|
997
1014
|
* @returns {Array}
|
|
998
1015
|
*/
|
|
999
1016
|
normalizedHash () {
|
|
1000
|
-
return Molecule.normalize(
|
|
1001
|
-
}
|
|
1002
|
-
|
|
1003
|
-
/**
|
|
1004
|
-
* Accept a string of letters and numbers, and outputs a collection of decimals representing each
|
|
1005
|
-
* character according to a pre-defined dictionary. Input string would typically be 64-character
|
|
1006
|
-
* hexadecimal string featuring numbers from 0 to 9 and characters from a to f - a total of 15
|
|
1007
|
-
* unique symbols. To ensure that string has an even number of symbols, convert it to Base 17
|
|
1008
|
-
* (adding G as a possible symbol). Map each symbol to integer values as follows:
|
|
1009
|
-
* 0 1 2 3 4 5 6 7 8 9 a b c d e f g
|
|
1010
|
-
* -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8
|
|
1011
|
-
*
|
|
1012
|
-
* @param {string} hash
|
|
1013
|
-
* @return {array}
|
|
1014
|
-
*/
|
|
1015
|
-
static enumerate ( hash ) {
|
|
1016
|
-
|
|
1017
|
-
const mapped = {
|
|
1018
|
-
'0': -8,
|
|
1019
|
-
'1': -7,
|
|
1020
|
-
'2': -6,
|
|
1021
|
-
'3': -5,
|
|
1022
|
-
'4': -4,
|
|
1023
|
-
'5': -3,
|
|
1024
|
-
'6': -2,
|
|
1025
|
-
'7': -1,
|
|
1026
|
-
'8': 0,
|
|
1027
|
-
'9': 1,
|
|
1028
|
-
'a': 2,
|
|
1029
|
-
'b': 3,
|
|
1030
|
-
'c': 4,
|
|
1031
|
-
'd': 5,
|
|
1032
|
-
'e': 6,
|
|
1033
|
-
'f': 7,
|
|
1034
|
-
'g': 8
|
|
1035
|
-
},
|
|
1036
|
-
target = [],
|
|
1037
|
-
hashList = hash.toLowerCase().split( '' );
|
|
1038
|
-
|
|
1039
|
-
for ( let index = 0, len = hashList.length; index < len; ++index ) {
|
|
1040
|
-
|
|
1041
|
-
const symbol = hashList[ index ];
|
|
1042
|
-
|
|
1043
|
-
if ( typeof mapped[ symbol ] !== 'undefined' ) {
|
|
1044
|
-
target[ index ] = mapped[ symbol ];
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
return target;
|
|
1017
|
+
return Molecule.normalize(Molecule.enumerate(this.molecularHash))
|
|
1049
1018
|
}
|
|
1050
|
-
|
|
1051
|
-
/**
|
|
1052
|
-
* Normalize enumerated string to ensure that the total sum of all symbols is exactly zero. This
|
|
1053
|
-
* ensures that exactly 50% of the WOTS+ key is leaked with each usage, ensuring predictable key
|
|
1054
|
-
* safety:
|
|
1055
|
-
* The sum of each symbol within Hm shall be presented by m
|
|
1056
|
-
* While m0 iterate across that set’s integers as Im:
|
|
1057
|
-
* If m0 and Im>-8 , let Im=Im-1
|
|
1058
|
-
* If m<0 and Im<8 , let Im=Im+1
|
|
1059
|
-
* If m=0, stop the iteration
|
|
1060
|
-
*
|
|
1061
|
-
* @param {array} mappedHashArray
|
|
1062
|
-
* @return {array}
|
|
1063
|
-
*/
|
|
1064
|
-
static normalize ( mappedHashArray ) {
|
|
1065
|
-
|
|
1066
|
-
let total = mappedHashArray.reduce( ( total, num ) => total + num );
|
|
1067
|
-
|
|
1068
|
-
const total_condition = total < 0;
|
|
1069
|
-
|
|
1070
|
-
while ( total < 0 || total > 0 ) {
|
|
1071
|
-
|
|
1072
|
-
for ( const index of Object.keys( mappedHashArray ) ) {
|
|
1073
|
-
|
|
1074
|
-
const condition = total_condition ? mappedHashArray[ index ] < 8 : mappedHashArray[ index ] > -8;
|
|
1075
|
-
|
|
1076
|
-
if ( condition ) {
|
|
1077
|
-
|
|
1078
|
-
const process = total_condition ? [ ++mappedHashArray[ index ], ++total ] : [ --mappedHashArray[ index ], --total ];
|
|
1079
|
-
|
|
1080
|
-
if ( 0 === total ) {
|
|
1081
|
-
break;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
|
|
1087
|
-
return mappedHashArray;
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
1019
|
}
|