@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
|
@@ -1,60 +1,104 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
/*
|
|
2
|
+
(
|
|
3
|
+
(/(
|
|
4
|
+
(//(
|
|
5
|
+
(///(
|
|
6
|
+
(/////(
|
|
7
|
+
(//////( )
|
|
8
|
+
(////////( (/)
|
|
9
|
+
(////////( (///)
|
|
10
|
+
(//////////( (////)
|
|
11
|
+
(//////////( (//////)
|
|
12
|
+
(////////////( (///////)
|
|
13
|
+
(/////////////( (/////////)
|
|
14
|
+
(//////////////( (///////////)
|
|
15
|
+
(///////////////( (/////////////)
|
|
16
|
+
(////////////////( (//////////////)
|
|
17
|
+
((((((((((((((((((( (((((((((((((((
|
|
18
|
+
((((((((((((((((((( ((((((((((((((
|
|
19
|
+
((((((((((((((((((( ((((((((((((((
|
|
20
|
+
(((((((((((((((((((( (((((((((((((
|
|
21
|
+
(((((((((((((((((((( ((((((((((((
|
|
22
|
+
((((((((((((((((((( ((((((((((((
|
|
23
|
+
((((((((((((((((((( ((((((((((
|
|
24
|
+
((((((((((((((((((/ (((((((((
|
|
25
|
+
(((((((((((((((((( ((((((((
|
|
26
|
+
((((((((((((((((( (((((((
|
|
27
|
+
(((((((((((((((((( (((((
|
|
28
|
+
################# ##
|
|
29
|
+
################ #
|
|
30
|
+
################# ##
|
|
31
|
+
%################ ###
|
|
32
|
+
###############( ####
|
|
33
|
+
############### ####
|
|
34
|
+
############### ######
|
|
35
|
+
%#############( (#######
|
|
36
|
+
%############# #########
|
|
37
|
+
############( ##########
|
|
38
|
+
########### #############
|
|
39
|
+
######### ##############
|
|
40
|
+
%######
|
|
41
|
+
|
|
42
|
+
Powered by Knish.IO: Connecting a Decentralized World
|
|
43
|
+
|
|
44
|
+
Please visit https://github.com/WishKnish/KnishIO-Client-JS for information.
|
|
45
|
+
|
|
46
|
+
License: https://github.com/WishKnish/KnishIO-Client-JS/blob/master/LICENSE
|
|
47
|
+
*/
|
|
48
|
+
import AtomIndexException from './../exception/AtomIndexException'
|
|
49
|
+
import AtomsMissingException from './../exception/AtomsMissingException'
|
|
50
|
+
import MolecularHashMismatchException from './../exception/MolecularHashMismatchException'
|
|
51
|
+
import MolecularHashMissingException from './../exception/MolecularHashMissingException'
|
|
52
|
+
import PolicyInvalidException from './../exception/PolicyInvalidException'
|
|
53
|
+
import SignatureMalformedException from './../exception/SignatureMalformedException'
|
|
54
|
+
import SignatureMismatchException from './../exception/SignatureMismatchException'
|
|
55
|
+
import TransferBalanceException from './../exception/TransferBalanceException'
|
|
56
|
+
import TransferMalformedException from './../exception/TransferMalformedException'
|
|
57
|
+
import TransferMismatchedException from './../exception/TransferMismatchedException'
|
|
58
|
+
import TransferRemainderException from './../exception/TransferRemainderException'
|
|
59
|
+
import TransferToSelfException from './../exception/TransferToSelfException'
|
|
60
|
+
import TransferUnbalancedException from './../exception/TransferUnbalancedException'
|
|
61
|
+
import MetaMissingException from './../exception/MetaMissingException'
|
|
62
|
+
import WrongTokenTypeException from './../exception/WrongTokenTypeException'
|
|
63
|
+
import BatchIdException from './../exception/BatchIdException'
|
|
64
|
+
import Atom from './../Atom'
|
|
65
|
+
import Meta from './../Meta'
|
|
66
|
+
import Wallet from './../Wallet'
|
|
67
|
+
import Rule from '../instance/Rules/Rule'
|
|
21
68
|
import {
|
|
22
69
|
base64ToHex,
|
|
23
70
|
chunkSubstr
|
|
24
|
-
} from './strings'
|
|
25
|
-
import
|
|
26
|
-
import Dot from './../libraries/Dot'
|
|
71
|
+
} from './strings'
|
|
72
|
+
import JsSHA from 'jssha'
|
|
73
|
+
import Dot from './../libraries/Dot'
|
|
27
74
|
|
|
28
75
|
/**
|
|
29
76
|
*
|
|
30
77
|
*/
|
|
31
78
|
export default class CheckMolecule {
|
|
32
|
-
|
|
33
|
-
|
|
34
79
|
/**
|
|
35
80
|
*
|
|
36
81
|
* @param molecule
|
|
37
82
|
*/
|
|
38
|
-
constructor (
|
|
39
|
-
|
|
83
|
+
constructor (molecule) {
|
|
40
84
|
// No molecular hash?
|
|
41
|
-
if (
|
|
42
|
-
throw new MolecularHashMissingException()
|
|
85
|
+
if (molecule.molecularHash === null) {
|
|
86
|
+
throw new MolecularHashMissingException()
|
|
43
87
|
}
|
|
44
88
|
|
|
45
89
|
// No atoms?
|
|
46
|
-
if (
|
|
47
|
-
throw new AtomsMissingException()
|
|
90
|
+
if (!molecule.atoms.length) {
|
|
91
|
+
throw new AtomsMissingException()
|
|
48
92
|
}
|
|
49
93
|
|
|
50
94
|
// Check atom indexes
|
|
51
|
-
for (
|
|
52
|
-
if (
|
|
53
|
-
throw new AtomIndexException()
|
|
95
|
+
for (const atom of molecule.atoms) {
|
|
96
|
+
if (atom.index === null) {
|
|
97
|
+
throw new AtomIndexException()
|
|
54
98
|
}
|
|
55
99
|
}
|
|
56
100
|
|
|
57
|
-
this.molecule = molecule
|
|
101
|
+
this.molecule = molecule
|
|
58
102
|
}
|
|
59
103
|
|
|
60
104
|
/**
|
|
@@ -62,18 +106,18 @@ export default class CheckMolecule {
|
|
|
62
106
|
* @param senderWallet
|
|
63
107
|
* @returns {false|*|boolean}
|
|
64
108
|
*/
|
|
65
|
-
verify (
|
|
66
|
-
return this.molecularHash()
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
109
|
+
verify (senderWallet) {
|
|
110
|
+
return this.molecularHash() &&
|
|
111
|
+
this.ots() &&
|
|
112
|
+
this.batchId() &&
|
|
113
|
+
this.continuId() &&
|
|
114
|
+
this.isotopeM() &&
|
|
115
|
+
this.isotopeT() &&
|
|
116
|
+
this.isotopeC() &&
|
|
117
|
+
this.isotopeU() &&
|
|
118
|
+
this.isotopeI() &&
|
|
119
|
+
this.isotopeR() &&
|
|
120
|
+
this.isotopeV(senderWallet)
|
|
77
121
|
}
|
|
78
122
|
|
|
79
123
|
/**
|
|
@@ -81,14 +125,13 @@ export default class CheckMolecule {
|
|
|
81
125
|
* @returns {boolean}
|
|
82
126
|
*/
|
|
83
127
|
continuId () {
|
|
128
|
+
const firstAtom = this.molecule.atoms[0]
|
|
84
129
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if ( firstAtom.token === 'USER' && this.molecule.getIsotopes( 'I' ).length < 1 ) {
|
|
88
|
-
throw new AtomsMissingException( 'Check::continuId() - Molecule is missing required ContinuID Atom!' );
|
|
130
|
+
if (firstAtom.token === 'USER' && this.molecule.getIsotopes('I').length < 1) {
|
|
131
|
+
throw new AtomsMissingException('Check::continuId() - Molecule is missing required ContinuID Atom!')
|
|
89
132
|
}
|
|
90
133
|
|
|
91
|
-
return true
|
|
134
|
+
return true
|
|
92
135
|
}
|
|
93
136
|
|
|
94
137
|
/**
|
|
@@ -96,29 +139,28 @@ export default class CheckMolecule {
|
|
|
96
139
|
* @returns {boolean}
|
|
97
140
|
*/
|
|
98
141
|
batchId () {
|
|
142
|
+
if (this.molecule.atoms.length > 0) {
|
|
143
|
+
const signingAtom = this.molecule.atoms[0]
|
|
99
144
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if ( signingAtom.isotope === 'V' && signingAtom.batchId !== null ) {
|
|
104
|
-
const atoms = this.molecule.getIsotopes( 'V' );
|
|
105
|
-
const remainderAtom = atoms[ atoms.length - 1 ];
|
|
145
|
+
if (signingAtom.isotope === 'V' && signingAtom.batchId !== null) {
|
|
146
|
+
const atoms = this.molecule.getIsotopes('V')
|
|
147
|
+
const remainderAtom = atoms[atoms.length - 1]
|
|
106
148
|
|
|
107
|
-
if (
|
|
108
|
-
throw new BatchIdException()
|
|
149
|
+
if (signingAtom.batchId !== remainderAtom.batchId) {
|
|
150
|
+
throw new BatchIdException()
|
|
109
151
|
}
|
|
110
152
|
|
|
111
|
-
for (
|
|
112
|
-
if (
|
|
113
|
-
throw new BatchIdException()
|
|
153
|
+
for (const atom of atoms) {
|
|
154
|
+
if (atom.batchId === null) {
|
|
155
|
+
throw new BatchIdException()
|
|
114
156
|
}
|
|
115
157
|
}
|
|
116
158
|
}
|
|
117
159
|
|
|
118
|
-
return true
|
|
160
|
+
return true
|
|
119
161
|
}
|
|
120
162
|
|
|
121
|
-
throw new BatchIdException()
|
|
163
|
+
throw new BatchIdException()
|
|
122
164
|
}
|
|
123
165
|
|
|
124
166
|
/**
|
|
@@ -126,18 +168,17 @@ export default class CheckMolecule {
|
|
|
126
168
|
* @returns {boolean}
|
|
127
169
|
*/
|
|
128
170
|
isotopeI () {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
throw new WrongTokenTypeException( `Check::isotopeI() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!` );
|
|
171
|
+
for (const atom of this.molecule.getIsotopes('I')) {
|
|
172
|
+
if (atom.token !== 'USER') {
|
|
173
|
+
throw new WrongTokenTypeException(`Check::isotopeI() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!`)
|
|
133
174
|
}
|
|
134
175
|
|
|
135
|
-
if (
|
|
136
|
-
throw new AtomIndexException(
|
|
176
|
+
if (atom.index === 0) {
|
|
177
|
+
throw new AtomIndexException(`Check::isotopeI() - Isotope "${ atom.isotope }" Atoms must have a non-zero index!`)
|
|
137
178
|
}
|
|
138
179
|
}
|
|
139
180
|
|
|
140
|
-
return true
|
|
181
|
+
return true
|
|
141
182
|
}
|
|
142
183
|
|
|
143
184
|
/**
|
|
@@ -145,18 +186,17 @@ export default class CheckMolecule {
|
|
|
145
186
|
* @returns {boolean}
|
|
146
187
|
*/
|
|
147
188
|
isotopeU () {
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
throw new WrongTokenTypeException( `Check::isotopeU() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!` );
|
|
189
|
+
for (const atom of this.molecule.getIsotopes('U')) {
|
|
190
|
+
if (atom.token !== 'AUTH') {
|
|
191
|
+
throw new WrongTokenTypeException(`Check::isotopeU() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!`)
|
|
152
192
|
}
|
|
153
193
|
|
|
154
|
-
if (
|
|
155
|
-
throw new AtomIndexException(
|
|
194
|
+
if (atom.index !== 0) {
|
|
195
|
+
throw new AtomIndexException(`Check::isotopeU() - Isotope "${ atom.isotope }" Atoms must have an index equal to 0!`)
|
|
156
196
|
}
|
|
157
197
|
}
|
|
158
198
|
|
|
159
|
-
return true
|
|
199
|
+
return true
|
|
160
200
|
}
|
|
161
201
|
|
|
162
202
|
/**
|
|
@@ -164,39 +204,34 @@ export default class CheckMolecule {
|
|
|
164
204
|
* @returns {boolean}
|
|
165
205
|
*/
|
|
166
206
|
isotopeM () {
|
|
207
|
+
const policyArray = ['readPolicy', 'writePolicy']
|
|
167
208
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
if ( atom.meta.length < 1 ) {
|
|
173
|
-
throw new MetaMissingException();
|
|
209
|
+
for (/** @type {Atom} */ const atom of this.molecule.getIsotopes('M')) {
|
|
210
|
+
if (atom.meta.length < 1) {
|
|
211
|
+
throw new MetaMissingException()
|
|
174
212
|
}
|
|
175
213
|
|
|
176
|
-
if (
|
|
177
|
-
throw new WrongTokenTypeException(
|
|
214
|
+
if (atom.token !== 'USER') {
|
|
215
|
+
throw new WrongTokenTypeException(`Check::isotopeM() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!`)
|
|
178
216
|
}
|
|
179
217
|
|
|
180
|
-
const metas = Meta.aggregateMeta(
|
|
181
|
-
|
|
182
|
-
for ( const key of policyArray ) {
|
|
183
|
-
let policy = metas[ key ];
|
|
184
|
-
|
|
185
|
-
if ( policy ) {
|
|
186
|
-
policy = JSON.parse( policy );
|
|
218
|
+
const metas = Meta.aggregateMeta(atom.meta)
|
|
187
219
|
|
|
188
|
-
|
|
220
|
+
for (const key of policyArray) {
|
|
221
|
+
let policy = metas[key]
|
|
189
222
|
|
|
190
|
-
|
|
223
|
+
if (policy) {
|
|
224
|
+
policy = JSON.parse(policy)
|
|
191
225
|
|
|
192
|
-
|
|
193
|
-
|
|
226
|
+
for (const [policyName, policyValue] of Object.entries(policy)) {
|
|
227
|
+
if (!policyArray.includes(policyName)) {
|
|
228
|
+
if (!Object.keys(metas).includes(policyName)) {
|
|
229
|
+
throw new PolicyInvalidException(`${ policyName } is missing from the meta.`)
|
|
194
230
|
}
|
|
195
231
|
|
|
196
|
-
for (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
throw new PolicyInvalidException( `${ value } does not correspond to the format of the policy.` );
|
|
232
|
+
for (const value of policyValue) {
|
|
233
|
+
if (!Wallet.isBundleHash(value) && !['all', 'self'].includes(value)) {
|
|
234
|
+
throw new PolicyInvalidException(`${ value } does not correspond to the format of the policy.`)
|
|
200
235
|
}
|
|
201
236
|
}
|
|
202
237
|
}
|
|
@@ -205,7 +240,7 @@ export default class CheckMolecule {
|
|
|
205
240
|
}
|
|
206
241
|
}
|
|
207
242
|
|
|
208
|
-
return true
|
|
243
|
+
return true
|
|
209
244
|
}
|
|
210
245
|
|
|
211
246
|
/**
|
|
@@ -213,18 +248,17 @@ export default class CheckMolecule {
|
|
|
213
248
|
* @returns {boolean}
|
|
214
249
|
*/
|
|
215
250
|
isotopeC () {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
throw new WrongTokenTypeException( `Check::isotopeC() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!` );
|
|
251
|
+
for (const atom of this.molecule.getIsotopes('C')) {
|
|
252
|
+
if (atom.token !== 'USER') {
|
|
253
|
+
throw new WrongTokenTypeException(`Check::isotopeC() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!`)
|
|
220
254
|
}
|
|
221
255
|
|
|
222
|
-
if (
|
|
223
|
-
throw new AtomIndexException(
|
|
256
|
+
if (atom.index !== 0) {
|
|
257
|
+
throw new AtomIndexException(`Check::isotopeC() - Isotope "${ atom.isotope }" Atoms must have an index equal to 0!`)
|
|
224
258
|
}
|
|
225
259
|
}
|
|
226
260
|
|
|
227
|
-
return true
|
|
261
|
+
return true
|
|
228
262
|
}
|
|
229
263
|
|
|
230
264
|
/**
|
|
@@ -232,35 +266,34 @@ export default class CheckMolecule {
|
|
|
232
266
|
* @returns {boolean}
|
|
233
267
|
*/
|
|
234
268
|
isotopeT () {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
throw new MetaMissingException( `Check::isotopeT() - Required meta field "${ key }" is missing!` );
|
|
269
|
+
for (const atom of this.molecule.getIsotopes('T')) {
|
|
270
|
+
const meta = atom.aggregatedMeta()
|
|
271
|
+
const metaType = String(atom.metaType).toLowerCase()
|
|
272
|
+
|
|
273
|
+
if (metaType === 'wallet') {
|
|
274
|
+
for (const key of ['position', 'bundle']) {
|
|
275
|
+
if (!Object.prototype.hasOwnProperty.call(meta, key) || !meta[key]) {
|
|
276
|
+
throw new MetaMissingException(`Check::isotopeT() - Required meta field "${ key }" is missing!`)
|
|
244
277
|
}
|
|
245
278
|
}
|
|
246
279
|
}
|
|
247
280
|
|
|
248
|
-
for (
|
|
249
|
-
if (
|
|
250
|
-
throw new MetaMissingException(
|
|
281
|
+
for (const key of ['token']) {
|
|
282
|
+
if (!Object.prototype.hasOwnProperty.call(meta, key) || !meta[key]) {
|
|
283
|
+
throw new MetaMissingException(`Check::isotopeT() - Required meta field "${ key }" is missing!`)
|
|
251
284
|
}
|
|
252
285
|
}
|
|
253
286
|
|
|
254
|
-
if (
|
|
255
|
-
throw new WrongTokenTypeException(
|
|
287
|
+
if (atom.token !== 'USER') {
|
|
288
|
+
throw new WrongTokenTypeException(`Check::isotopeT() - "${ atom.token }" is not a valid Token slug for "${ atom.isotope }" isotope Atoms!`)
|
|
256
289
|
}
|
|
257
290
|
|
|
258
|
-
if (
|
|
259
|
-
throw new AtomIndexException(
|
|
291
|
+
if (atom.index !== 0) {
|
|
292
|
+
throw new AtomIndexException(`Check::isotopeT() - Isotope "${ atom.isotope }" Atoms must have an index equal to 0!`)
|
|
260
293
|
}
|
|
261
294
|
}
|
|
262
295
|
|
|
263
|
-
return true
|
|
296
|
+
return true
|
|
264
297
|
}
|
|
265
298
|
|
|
266
299
|
/**
|
|
@@ -268,36 +301,35 @@ export default class CheckMolecule {
|
|
|
268
301
|
* @returns {boolean}
|
|
269
302
|
*/
|
|
270
303
|
isotopeR () {
|
|
304
|
+
for (const atom of this.molecule.getIsotopes('R')) {
|
|
305
|
+
const metas = atom.aggregatedMeta()
|
|
271
306
|
|
|
272
|
-
|
|
273
|
-
|
|
307
|
+
if (metas.policy) {
|
|
308
|
+
const policy = JSON.parse(metas.policy)
|
|
274
309
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
if ( !Object.keys( policy ).every( i => [ 'read', 'write' ].includes( i ) ) ) {
|
|
279
|
-
throw new MetaMissingException( 'Check::isotopeR() - Mixing rules with politics!' );
|
|
310
|
+
if (!Object.keys(policy).every(i => ['read', 'write'].includes(i))) {
|
|
311
|
+
throw new MetaMissingException('Check::isotopeR() - Mixing rules with politics!')
|
|
280
312
|
}
|
|
281
313
|
}
|
|
282
314
|
|
|
283
|
-
if (
|
|
284
|
-
const rules = JSON.parse(
|
|
315
|
+
if (metas.rule) {
|
|
316
|
+
const rules = JSON.parse(metas.rule)
|
|
285
317
|
|
|
286
|
-
if (
|
|
287
|
-
throw new MetaMissingException(
|
|
318
|
+
if (!Array.isArray(rules)) {
|
|
319
|
+
throw new MetaMissingException('Check::isotopeR() - Incorrect rule format!')
|
|
288
320
|
}
|
|
289
321
|
|
|
290
|
-
for (
|
|
291
|
-
Rule.toObject(
|
|
322
|
+
for (const item of rules) {
|
|
323
|
+
Rule.toObject(item)
|
|
292
324
|
}
|
|
293
325
|
|
|
294
|
-
if (
|
|
295
|
-
throw new MetaMissingException(
|
|
326
|
+
if (rules.length < 1) {
|
|
327
|
+
throw new MetaMissingException('Check::isotopeR() - No rules!')
|
|
296
328
|
}
|
|
297
329
|
}
|
|
298
330
|
}
|
|
299
331
|
|
|
300
|
-
return true
|
|
332
|
+
return true
|
|
301
333
|
}
|
|
302
334
|
|
|
303
335
|
/**
|
|
@@ -305,111 +337,102 @@ export default class CheckMolecule {
|
|
|
305
337
|
* @param senderWallet
|
|
306
338
|
* @returns {boolean}
|
|
307
339
|
*/
|
|
308
|
-
isotopeV (
|
|
309
|
-
|
|
310
|
-
const isotopeV = this.molecule.getIsotopes( 'V' );
|
|
340
|
+
isotopeV (senderWallet = null) {
|
|
341
|
+
const isotopeV = this.molecule.getIsotopes('V')
|
|
311
342
|
|
|
312
|
-
if (
|
|
313
|
-
return true
|
|
343
|
+
if (isotopeV.length === 0) {
|
|
344
|
+
return true
|
|
314
345
|
}
|
|
315
346
|
|
|
316
|
-
const firstAtom = this.molecule.atoms[
|
|
347
|
+
const firstAtom = this.molecule.atoms[0]
|
|
317
348
|
|
|
318
|
-
if (
|
|
349
|
+
if (firstAtom.isotope === 'V' && isotopeV.length === 2) {
|
|
350
|
+
const endAtom = isotopeV[isotopeV.length - 1]
|
|
319
351
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
if ( firstAtom.token !== endAtom.token ) {
|
|
323
|
-
throw new TransferMismatchedException();
|
|
352
|
+
if (firstAtom.token !== endAtom.token) {
|
|
353
|
+
throw new TransferMismatchedException()
|
|
324
354
|
}
|
|
325
355
|
|
|
326
|
-
if (
|
|
327
|
-
throw new TransferMalformedException()
|
|
356
|
+
if (endAtom.value < 0) {
|
|
357
|
+
throw new TransferMalformedException()
|
|
328
358
|
}
|
|
329
359
|
|
|
330
|
-
return true
|
|
360
|
+
return true
|
|
331
361
|
}
|
|
332
362
|
|
|
363
|
+
let sum = 0
|
|
364
|
+
let value = 0
|
|
333
365
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
for ( let index in this.molecule.atoms ) {
|
|
338
|
-
|
|
339
|
-
if ( this.molecule.atoms.hasOwnProperty( index ) ) {
|
|
340
|
-
|
|
341
|
-
const vAtom = this.molecule.atoms[ index ];
|
|
366
|
+
for (const index in this.molecule.atoms) {
|
|
367
|
+
if (Object.prototype.hasOwnProperty.call(this.molecule.atoms, index)) {
|
|
368
|
+
const vAtom = this.molecule.atoms[index]
|
|
342
369
|
|
|
343
370
|
// Not V? Next...
|
|
344
|
-
if (
|
|
345
|
-
continue
|
|
371
|
+
if (vAtom.isotope !== 'V') {
|
|
372
|
+
continue
|
|
346
373
|
}
|
|
347
374
|
|
|
348
375
|
// Making sure we're in integer land
|
|
349
|
-
value = vAtom.value * 1
|
|
376
|
+
value = vAtom.value * 1
|
|
350
377
|
|
|
351
|
-
if (
|
|
352
|
-
throw new TypeError(
|
|
378
|
+
if (Number.isNaN(value)) {
|
|
379
|
+
throw new TypeError('Invalid isotope "V" values')
|
|
353
380
|
}
|
|
354
381
|
|
|
355
382
|
// Making sure all V atoms of the same token
|
|
356
|
-
if (
|
|
357
|
-
throw new TransferMismatchedException()
|
|
383
|
+
if (vAtom.token !== firstAtom.token) {
|
|
384
|
+
throw new TransferMismatchedException()
|
|
358
385
|
}
|
|
359
386
|
|
|
360
387
|
// Checking non-primary atoms
|
|
361
|
-
if (
|
|
362
|
-
|
|
388
|
+
if (index > 0) {
|
|
363
389
|
// Negative V atom in a non-primary position?
|
|
364
|
-
if (
|
|
365
|
-
throw new TransferMalformedException()
|
|
390
|
+
if (value < 0) {
|
|
391
|
+
throw new TransferMalformedException()
|
|
366
392
|
}
|
|
367
393
|
|
|
368
394
|
// Cannot be sending and receiving from the same address
|
|
369
|
-
if (
|
|
370
|
-
throw new TransferToSelfException()
|
|
395
|
+
if (vAtom.walletAddress === firstAtom.walletAddress) {
|
|
396
|
+
throw new TransferToSelfException()
|
|
371
397
|
}
|
|
372
|
-
|
|
373
398
|
}
|
|
374
399
|
|
|
375
400
|
// Adding this Atom's value to the total sum
|
|
376
|
-
sum += value
|
|
401
|
+
sum += value
|
|
377
402
|
}
|
|
378
403
|
}
|
|
379
404
|
|
|
380
405
|
// Does the total sum of all atoms equal the remainder atom's value? (all other atoms must add up to zero)
|
|
381
|
-
if (
|
|
382
|
-
throw new TransferUnbalancedException()
|
|
406
|
+
if (sum !== value) {
|
|
407
|
+
throw new TransferUnbalancedException()
|
|
383
408
|
}
|
|
384
409
|
|
|
385
410
|
// If we're provided with a senderWallet argument, we can perform additional checks
|
|
386
|
-
if (
|
|
411
|
+
if (senderWallet) {
|
|
412
|
+
value = firstAtom.value * 1
|
|
387
413
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if ( Number.isNaN( value ) ) {
|
|
391
|
-
throw new TypeError( 'Invalid isotope "V" values' );
|
|
414
|
+
if (Number.isNaN(value)) {
|
|
415
|
+
throw new TypeError('Invalid isotope "V" values')
|
|
392
416
|
}
|
|
393
417
|
|
|
394
|
-
const remainder =
|
|
418
|
+
const remainder = senderWallet.balance + value
|
|
395
419
|
|
|
396
420
|
// Is there enough balance to send?
|
|
397
|
-
if (
|
|
398
|
-
throw new TransferBalanceException()
|
|
421
|
+
if (remainder < 0) {
|
|
422
|
+
throw new TransferBalanceException()
|
|
399
423
|
}
|
|
400
424
|
|
|
401
425
|
// Does the remainder match what should be there in the source wallet, if provided?
|
|
402
|
-
if (
|
|
403
|
-
throw new TransferRemainderException()
|
|
426
|
+
if (remainder !== sum) {
|
|
427
|
+
throw new TransferRemainderException()
|
|
404
428
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
throw new TransferRemainderException();
|
|
429
|
+
} else if (value !== 0) {
|
|
430
|
+
// No senderWallet, but have a remainder?
|
|
431
|
+
throw new TransferRemainderException()
|
|
409
432
|
}
|
|
410
433
|
|
|
411
434
|
// Looks like we passed all the tests!
|
|
412
|
-
return true
|
|
435
|
+
return true
|
|
413
436
|
}
|
|
414
437
|
|
|
415
438
|
/**
|
|
@@ -418,15 +441,14 @@ export default class CheckMolecule {
|
|
|
418
441
|
* @returns {boolean}
|
|
419
442
|
*/
|
|
420
443
|
molecularHash () {
|
|
421
|
-
|
|
422
|
-
if ( this.molecule.molecularHash !== Atom.hashAtoms( {
|
|
444
|
+
if (this.molecule.molecularHash !== Atom.hashAtoms({
|
|
423
445
|
atoms: this.molecule.atoms
|
|
424
|
-
}
|
|
425
|
-
throw new MolecularHashMismatchException()
|
|
446
|
+
})) {
|
|
447
|
+
throw new MolecularHashMismatchException()
|
|
426
448
|
}
|
|
427
449
|
|
|
428
450
|
// Looks like we passed all the tests!
|
|
429
|
-
return true
|
|
451
|
+
return true
|
|
430
452
|
}
|
|
431
453
|
|
|
432
454
|
/**
|
|
@@ -437,72 +459,71 @@ export default class CheckMolecule {
|
|
|
437
459
|
* @returns {boolean}
|
|
438
460
|
*/
|
|
439
461
|
ots () {
|
|
440
|
-
|
|
441
462
|
// Convert Hm to numeric notation via EnumerateMolecule(Hm)
|
|
442
|
-
const normalizedHash = this.molecule.normalizedHash()
|
|
463
|
+
const normalizedHash = this.molecule.normalizedHash()
|
|
443
464
|
|
|
444
465
|
// Rebuilding OTS out of all the atoms
|
|
445
466
|
let ots = this.molecule.atoms.map(
|
|
446
467
|
atom => atom.otsFragment
|
|
447
468
|
).reduce(
|
|
448
|
-
(
|
|
449
|
-
)
|
|
469
|
+
(accumulator, otsFragment) => accumulator + otsFragment
|
|
470
|
+
)
|
|
450
471
|
|
|
451
472
|
// Wrong size? Maybe it's compressed
|
|
452
|
-
if (
|
|
453
|
-
|
|
473
|
+
if (ots.length !== 2048) {
|
|
454
474
|
// Attempting decompression
|
|
455
|
-
ots = base64ToHex(
|
|
475
|
+
ots = base64ToHex(ots)
|
|
456
476
|
|
|
457
477
|
// Still wrong? That's a failure
|
|
458
|
-
if (
|
|
459
|
-
throw new SignatureMalformedException()
|
|
478
|
+
if (ots.length !== 2048) {
|
|
479
|
+
throw new SignatureMalformedException()
|
|
460
480
|
}
|
|
461
481
|
}
|
|
462
482
|
|
|
463
483
|
// Subdivide Kk into 16 segments of 256 bytes (128 characters) each
|
|
464
|
-
const otsChunks = chunkSubstr(
|
|
465
|
-
|
|
466
|
-
let keyFragments = '';
|
|
484
|
+
const otsChunks = chunkSubstr(ots, 128)
|
|
467
485
|
|
|
468
|
-
|
|
486
|
+
let keyFragments = ''
|
|
469
487
|
|
|
470
|
-
|
|
488
|
+
for (const index in otsChunks) {
|
|
489
|
+
let workingChunk = otsChunks[index]
|
|
471
490
|
|
|
472
|
-
for (
|
|
473
|
-
workingChunk =
|
|
491
|
+
for (let iterationCount = 0, condition = 8 + normalizedHash[index]; iterationCount < condition; iterationCount++) {
|
|
492
|
+
workingChunk = (new JsSHA('SHAKE256', 'TEXT')).update(workingChunk).getHash('HEX', { outputLen: 512 })
|
|
474
493
|
}
|
|
475
494
|
|
|
476
|
-
keyFragments += workingChunk
|
|
495
|
+
keyFragments += workingChunk
|
|
477
496
|
}
|
|
478
497
|
|
|
479
498
|
// Absorb the hashed Kk into the sponge to receive the digest Dk
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
|
|
499
|
+
const digestSponge = new JsSHA('SHAKE256', 'TEXT')
|
|
500
|
+
digestSponge.update(keyFragments)
|
|
501
|
+
const digest = digestSponge.getHash('HEX', { outputLen: 8192 })
|
|
483
502
|
|
|
503
|
+
// Squeeze the sponge to retrieve a 128 byte (64 character) string that should match the sender’s wallet address
|
|
504
|
+
const addressSponge = new JsSHA('SHAKE256', 'TEXT')
|
|
505
|
+
addressSponge.update(digest)
|
|
506
|
+
const address = addressSponge.getHash('HEX', { outputLen: 256 })
|
|
484
507
|
|
|
485
508
|
// Signing atom
|
|
486
|
-
|
|
509
|
+
const signingAtom = this.molecule.atoms[0]
|
|
487
510
|
|
|
488
511
|
// Get a signing address
|
|
489
|
-
let signingAddress = signingAtom.walletAddress
|
|
512
|
+
let signingAddress = signingAtom.walletAddress
|
|
490
513
|
|
|
491
514
|
// Get signing wallet from first atom's metas
|
|
492
|
-
|
|
515
|
+
const signingWallet = Dot.get(signingAtom.aggregatedMeta(), 'signingWallet')
|
|
493
516
|
|
|
494
517
|
// Try to get custom signing address from the metas (local molecule with server secret)
|
|
495
|
-
if (
|
|
496
|
-
signingAddress = Dot.get(
|
|
518
|
+
if (signingWallet) {
|
|
519
|
+
signingAddress = Dot.get(JSON.parse(signingWallet), 'address')
|
|
497
520
|
}
|
|
498
521
|
|
|
499
|
-
if (
|
|
500
|
-
throw new SignatureMismatchException()
|
|
522
|
+
if (address !== signingAddress) {
|
|
523
|
+
throw new SignatureMismatchException()
|
|
501
524
|
}
|
|
502
525
|
|
|
503
526
|
// Looks like we passed all the tests!
|
|
504
|
-
return true
|
|
527
|
+
return true
|
|
505
528
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
529
|
}
|