@neuraiproject/neurai-assets 1.0.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.
- package/README.md +522 -0
- package/examples/01-create-root-asset.js +71 -0
- package/examples/02-create-sub-asset.js +79 -0
- package/examples/03-create-nfts.js +140 -0
- package/examples/04-reissue-asset.js +164 -0
- package/examples/05-create-qualifier-and-tag.js +209 -0
- package/examples/06-create-restricted-asset.js +223 -0
- package/examples/07-freeze-and-unfreeze.js +292 -0
- package/examples/08-query-assets.js +332 -0
- package/examples/09-wallet-integration.js +320 -0
- package/examples/README.md +319 -0
- package/package.json +43 -0
- package/src/NeuraiAssets.js +468 -0
- package/src/builders/BaseAssetTransactionBuilder.js +303 -0
- package/src/builders/FreezeAddressBuilder.js +271 -0
- package/src/builders/IssueQualifierBuilder.js +251 -0
- package/src/builders/IssueRestrictedBuilder.js +187 -0
- package/src/builders/IssueRootBuilder.js +173 -0
- package/src/builders/IssueSubBuilder.js +237 -0
- package/src/builders/IssueUniqueBuilder.js +255 -0
- package/src/builders/ReissueBuilder.js +246 -0
- package/src/builders/ReissueRestrictedBuilder.js +264 -0
- package/src/builders/TagAddressBuilder.js +243 -0
- package/src/builders/index.js +38 -0
- package/src/constants/assetTypes.js +23 -0
- package/src/constants/burnAddresses.js +65 -0
- package/src/constants/fees.js +61 -0
- package/src/constants/index.js +44 -0
- package/src/constants/networks.js +112 -0
- package/src/errors/AssetErrors.js +135 -0
- package/src/errors/ValidationErrors.js +87 -0
- package/src/errors/index.js +56 -0
- package/src/index.js +68 -0
- package/src/managers/BurnManager.js +222 -0
- package/src/managers/OutputOrderer.js +289 -0
- package/src/managers/OwnerTokenManager.js +265 -0
- package/src/managers/UTXOSelector.js +309 -0
- package/src/managers/index.js +16 -0
- package/src/queries/AssetQueries.js +447 -0
- package/src/queries/index.js +10 -0
- package/src/utils/amountConverter.js +115 -0
- package/src/utils/assetNameParser.js +203 -0
- package/src/utils/index.js +16 -0
- package/src/utils/networkDetector.js +144 -0
- package/src/utils/outputFormatter.js +292 -0
- package/src/validators/amountValidator.js +149 -0
- package/src/validators/assetNameValidator.js +296 -0
- package/src/validators/index.js +16 -0
- package/src/validators/ipfsValidator.js +101 -0
- package/src/validators/verifierValidator.js +146 -0
- package/tests/README.md +126 -0
- package/tests/integration/assetLifecycle.test.js +244 -0
- package/tests/mocks/rpcMock.js +156 -0
- package/tests/unit/NeuraiAssets.test.js +217 -0
- package/tests/unit/utils/amountConverter.test.js +171 -0
- package/tests/unit/utils/assetNameParser.test.js +203 -0
- package/tests/unit/validators/amountValidator.test.js +143 -0
- package/tests/unit/validators/assetNameValidator.test.js +228 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for AmountValidator
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { expect } = require('chai');
|
|
6
|
+
const AmountValidator = require('../../../src/validators/amountValidator');
|
|
7
|
+
const { InvalidAmountError, InvalidUnitsError } = require('../../../src/errors');
|
|
8
|
+
|
|
9
|
+
describe('AmountValidator', () => {
|
|
10
|
+
describe('validate', () => {
|
|
11
|
+
it('should validate correct amounts', () => {
|
|
12
|
+
expect(AmountValidator.validate(100, 0)).to.be.true;
|
|
13
|
+
expect(AmountValidator.validate(1.5, 2)).to.be.true;
|
|
14
|
+
expect(AmountValidator.validate(1000000, 8)).to.be.true;
|
|
15
|
+
expect(AmountValidator.validate(1, 0)).to.be.true;
|
|
16
|
+
expect(AmountValidator.validate(1.00000001, 8)).to.be.true;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should reject non-numeric amounts', () => {
|
|
20
|
+
expect(() => AmountValidator.validate('100', 0))
|
|
21
|
+
.to.throw(InvalidAmountError, 'must be a valid number');
|
|
22
|
+
|
|
23
|
+
expect(() => AmountValidator.validate(NaN, 0))
|
|
24
|
+
.to.throw(InvalidAmountError, 'must be a valid number');
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should reject zero or negative amounts', () => {
|
|
28
|
+
expect(() => AmountValidator.validate(0, 0))
|
|
29
|
+
.to.throw(InvalidAmountError, 'must be greater than 0');
|
|
30
|
+
|
|
31
|
+
expect(() => AmountValidator.validate(-100, 0))
|
|
32
|
+
.to.throw(InvalidAmountError, 'must be greater than 0');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('should reject amounts that are too large', () => {
|
|
36
|
+
expect(() => AmountValidator.validate(22000000000, 0))
|
|
37
|
+
.to.throw(InvalidAmountError, 'cannot exceed');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should reject amounts with more decimals than units allow', () => {
|
|
41
|
+
expect(() => AmountValidator.validate(1.123, 2))
|
|
42
|
+
.to.throw(InvalidAmountError, 'decimal places but units is');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should reject invalid units', () => {
|
|
46
|
+
expect(() => AmountValidator.validate(100, -1))
|
|
47
|
+
.to.throw(InvalidUnitsError);
|
|
48
|
+
|
|
49
|
+
expect(() => AmountValidator.validate(100, 9))
|
|
50
|
+
.to.throw(InvalidUnitsError);
|
|
51
|
+
|
|
52
|
+
expect(() => AmountValidator.validate(100, 1.5))
|
|
53
|
+
.to.throw(InvalidUnitsError, 'must be an integer');
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('validateUnits', () => {
|
|
58
|
+
it('should validate correct units', () => {
|
|
59
|
+
expect(AmountValidator.validateUnits(0)).to.be.true;
|
|
60
|
+
expect(AmountValidator.validateUnits(4)).to.be.true;
|
|
61
|
+
expect(AmountValidator.validateUnits(8)).to.be.true;
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should reject units outside range', () => {
|
|
65
|
+
expect(() => AmountValidator.validateUnits(-1))
|
|
66
|
+
.to.throw(InvalidUnitsError, 'must be between');
|
|
67
|
+
|
|
68
|
+
expect(() => AmountValidator.validateUnits(9))
|
|
69
|
+
.to.throw(InvalidUnitsError, 'must be between');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should reject non-integer units', () => {
|
|
73
|
+
expect(() => AmountValidator.validateUnits(2.5))
|
|
74
|
+
.to.throw(InvalidUnitsError, 'must be an integer');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should reject non-numeric units', () => {
|
|
78
|
+
expect(() => AmountValidator.validateUnits('4'))
|
|
79
|
+
.to.throw(InvalidUnitsError, 'must be a valid number');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('validateQualifierQuantity', () => {
|
|
84
|
+
it('should validate correct qualifier quantities', () => {
|
|
85
|
+
expect(AmountValidator.validateQualifierQuantity(1)).to.be.true;
|
|
86
|
+
expect(AmountValidator.validateQualifierQuantity(5)).to.be.true;
|
|
87
|
+
expect(AmountValidator.validateQualifierQuantity(10)).to.be.true;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should reject quantities outside 1-10 range', () => {
|
|
91
|
+
expect(() => AmountValidator.validateQualifierQuantity(0))
|
|
92
|
+
.to.throw(InvalidAmountError, 'must be between');
|
|
93
|
+
|
|
94
|
+
expect(() => AmountValidator.validateQualifierQuantity(11))
|
|
95
|
+
.to.throw(InvalidAmountError, 'must be between');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should reject non-integer quantities', () => {
|
|
99
|
+
expect(() => AmountValidator.validateQualifierQuantity(5.5))
|
|
100
|
+
.to.throw(InvalidAmountError, 'must be an integer');
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
describe('validateOwnerTokenQuantity', () => {
|
|
105
|
+
it('should validate owner token quantity of 1', () => {
|
|
106
|
+
expect(AmountValidator.validateOwnerTokenQuantity(1)).to.be.true;
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should reject any quantity other than 1', () => {
|
|
110
|
+
expect(() => AmountValidator.validateOwnerTokenQuantity(0))
|
|
111
|
+
.to.throw(InvalidAmountError, 'must be exactly 1');
|
|
112
|
+
|
|
113
|
+
expect(() => AmountValidator.validateOwnerTokenQuantity(2))
|
|
114
|
+
.to.throw(InvalidAmountError, 'must be exactly 1');
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('getDecimalPlaces', () => {
|
|
119
|
+
it('should correctly count decimal places', () => {
|
|
120
|
+
expect(AmountValidator.getDecimalPlaces(100)).to.equal(0);
|
|
121
|
+
expect(AmountValidator.getDecimalPlaces(1.5)).to.equal(1);
|
|
122
|
+
expect(AmountValidator.getDecimalPlaces(1.25)).to.equal(2);
|
|
123
|
+
expect(AmountValidator.getDecimalPlaces(0.00000001)).to.equal(8);
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('should handle scientific notation', () => {
|
|
127
|
+
expect(AmountValidator.getDecimalPlaces(1e-8)).to.equal(8);
|
|
128
|
+
expect(AmountValidator.getDecimalPlaces(1.5e2)).to.equal(0);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('validateSum', () => {
|
|
133
|
+
it('should validate sums within limits', () => {
|
|
134
|
+
expect(AmountValidator.validateSum(1000, 2000)).to.be.true;
|
|
135
|
+
expect(AmountValidator.validateSum(10000000000, 10000000000)).to.be.true;
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should reject sums that exceed maximum', () => {
|
|
139
|
+
expect(() => AmountValidator.validateSum(20000000000, 5000000000))
|
|
140
|
+
.to.throw(InvalidAmountError, 'exceeds maximum');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for AssetNameValidator
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
const { expect } = require('chai');
|
|
6
|
+
const AssetNameValidator = require('../../../src/validators/assetNameValidator');
|
|
7
|
+
const { InvalidAssetNameError } = require('../../../src/errors');
|
|
8
|
+
|
|
9
|
+
describe('AssetNameValidator', () => {
|
|
10
|
+
describe('validateRoot', () => {
|
|
11
|
+
it('should validate correct ROOT asset names', () => {
|
|
12
|
+
expect(AssetNameValidator.validateRoot('MYTOKEN')).to.be.true;
|
|
13
|
+
expect(AssetNameValidator.validateRoot('TEST')).to.be.true;
|
|
14
|
+
expect(AssetNameValidator.validateRoot('MY_TOKEN')).to.be.true;
|
|
15
|
+
expect(AssetNameValidator.validateRoot('MY.TOKEN')).to.be.true;
|
|
16
|
+
expect(AssetNameValidator.validateRoot('TOKEN123')).to.be.true;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('should reject names that are too short', () => {
|
|
20
|
+
expect(() => AssetNameValidator.validateRoot('AB'))
|
|
21
|
+
.to.throw(InvalidAssetNameError, 'ROOT asset name must be');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should reject names that are too long', () => {
|
|
25
|
+
expect(() => AssetNameValidator.validateRoot('A'.repeat(31)))
|
|
26
|
+
.to.throw(InvalidAssetNameError, 'ROOT asset name must be');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should reject lowercase names', () => {
|
|
30
|
+
expect(() => AssetNameValidator.validateRoot('mytoken'))
|
|
31
|
+
.to.throw(InvalidAssetNameError, 'must be uppercase');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should reject names starting with restricted characters', () => {
|
|
35
|
+
expect(() => AssetNameValidator.validateRoot('ATOKEN'))
|
|
36
|
+
.to.throw(InvalidAssetNameError, 'cannot start with');
|
|
37
|
+
|
|
38
|
+
expect(() => AssetNameValidator.validateRoot('ZTOKEN'))
|
|
39
|
+
.to.throw(InvalidAssetNameError, 'cannot start with');
|
|
40
|
+
|
|
41
|
+
expect(() => AssetNameValidator.validateRoot('.TOKEN'))
|
|
42
|
+
.to.throw(InvalidAssetNameError, 'cannot start with');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should reject names with invalid characters', () => {
|
|
46
|
+
expect(() => AssetNameValidator.validateRoot('MY-TOKEN'))
|
|
47
|
+
.to.throw(InvalidAssetNameError, 'can only contain');
|
|
48
|
+
|
|
49
|
+
expect(() => AssetNameValidator.validateRoot('MY TOKEN'))
|
|
50
|
+
.to.throw(InvalidAssetNameError, 'can only contain');
|
|
51
|
+
|
|
52
|
+
expect(() => AssetNameValidator.validateRoot('MY@TOKEN'))
|
|
53
|
+
.to.throw(InvalidAssetNameError, 'can only contain');
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should reject reserved names', () => {
|
|
57
|
+
expect(() => AssetNameValidator.validateRoot('XNA'))
|
|
58
|
+
.to.throw(InvalidAssetNameError, 'reserved asset name');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should reject non-string inputs', () => {
|
|
62
|
+
expect(() => AssetNameValidator.validateRoot(null))
|
|
63
|
+
.to.throw(InvalidAssetNameError, 'must be a non-empty string');
|
|
64
|
+
|
|
65
|
+
expect(() => AssetNameValidator.validateRoot(123))
|
|
66
|
+
.to.throw(InvalidAssetNameError, 'must be a non-empty string');
|
|
67
|
+
|
|
68
|
+
expect(() => AssetNameValidator.validateRoot(''))
|
|
69
|
+
.to.throw(InvalidAssetNameError, 'must be a non-empty string');
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('validateSub', () => {
|
|
74
|
+
it('should validate correct SUB asset names', () => {
|
|
75
|
+
expect(AssetNameValidator.validateSub('MYTOKEN/SUB')).to.be.true;
|
|
76
|
+
expect(AssetNameValidator.validateSub('TEST/ALPHA')).to.be.true;
|
|
77
|
+
expect(AssetNameValidator.validateSub('TOKEN/SUB_1')).to.be.true;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('should reject names without separator', () => {
|
|
81
|
+
expect(() => AssetNameValidator.validateSub('MYTOKEN'))
|
|
82
|
+
.to.throw(InvalidAssetNameError, 'must be in');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should reject names with multiple separators', () => {
|
|
86
|
+
expect(() => AssetNameValidator.validateSub('MY/TOKEN/SUB'))
|
|
87
|
+
.to.throw(InvalidAssetNameError, 'must be in');
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('should reject invalid root parts', () => {
|
|
91
|
+
expect(() => AssetNameValidator.validateSub('AB/SUB'))
|
|
92
|
+
.to.throw(InvalidAssetNameError);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should reject invalid sub parts', () => {
|
|
96
|
+
expect(() => AssetNameValidator.validateSub('MYTOKEN/ab'))
|
|
97
|
+
.to.throw(InvalidAssetNameError, 'must be uppercase');
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
describe('validateUnique', () => {
|
|
102
|
+
it('should validate correct UNIQUE asset names', () => {
|
|
103
|
+
expect(AssetNameValidator.validateUnique('MYTOKEN#NFT1')).to.be.true;
|
|
104
|
+
expect(AssetNameValidator.validateUnique('TEST#ALPHA')).to.be.true;
|
|
105
|
+
expect(AssetNameValidator.validateUnique('TOKEN#123')).to.be.true;
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should reject names without # separator', () => {
|
|
109
|
+
expect(() => AssetNameValidator.validateUnique('MYTOKEN'))
|
|
110
|
+
.to.throw(InvalidAssetNameError, 'must be in ROOT#TAG format');
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('should reject names with multiple # separators', () => {
|
|
114
|
+
expect(() => AssetNameValidator.validateUnique('MY#TOKEN#TAG'))
|
|
115
|
+
.to.throw(InvalidAssetNameError);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should reject invalid root parts', () => {
|
|
119
|
+
expect(() => AssetNameValidator.validateUnique('AB#TAG'))
|
|
120
|
+
.to.throw(InvalidAssetNameError);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should reject invalid tag parts', () => {
|
|
124
|
+
expect(() => AssetNameValidator.validateUnique('MYTOKEN#ab'))
|
|
125
|
+
.to.throw(InvalidAssetNameError, 'must be uppercase');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
describe('validateQualifier', () => {
|
|
130
|
+
it('should validate correct QUALIFIER names', () => {
|
|
131
|
+
expect(AssetNameValidator.validateQualifier('#KYC')).to.be.true;
|
|
132
|
+
expect(AssetNameValidator.validateQualifier('#ACCREDITED')).to.be.true;
|
|
133
|
+
expect(AssetNameValidator.validateQualifier('#TEST_1')).to.be.true;
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should validate correct SUB_QUALIFIER names', () => {
|
|
137
|
+
expect(AssetNameValidator.validateQualifier('#KYC/TIER1')).to.be.true;
|
|
138
|
+
expect(AssetNameValidator.validateQualifier('#TEST/ALPHA')).to.be.true;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('should reject names without # prefix', () => {
|
|
142
|
+
expect(() => AssetNameValidator.validateQualifier('KYC'))
|
|
143
|
+
.to.throw(InvalidAssetNameError, 'must start with #');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should reject lowercase qualifier names', () => {
|
|
147
|
+
expect(() => AssetNameValidator.validateQualifier('#kyc'))
|
|
148
|
+
.to.throw(InvalidAssetNameError, 'must be uppercase');
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('should reject qualifiers with invalid characters', () => {
|
|
152
|
+
expect(() => AssetNameValidator.validateQualifier('#KYC.TEST'))
|
|
153
|
+
.to.throw(InvalidAssetNameError, 'can only contain');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('validateRestricted', () => {
|
|
158
|
+
it('should validate correct RESTRICTED asset names', () => {
|
|
159
|
+
expect(AssetNameValidator.validateRestricted('$SECURITY')).to.be.true;
|
|
160
|
+
expect(AssetNameValidator.validateRestricted('$TOKEN')).to.be.true;
|
|
161
|
+
expect(AssetNameValidator.validateRestricted('$MY_TOKEN')).to.be.true;
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should reject names without $ prefix', () => {
|
|
165
|
+
expect(() => AssetNameValidator.validateRestricted('SECURITY'))
|
|
166
|
+
.to.throw(InvalidAssetNameError, 'must start with $');
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('should reject invalid base names', () => {
|
|
170
|
+
expect(() => AssetNameValidator.validateRestricted('$ab'))
|
|
171
|
+
.to.throw(InvalidAssetNameError);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('validateOwnerToken', () => {
|
|
176
|
+
it('should validate correct owner token names', () => {
|
|
177
|
+
expect(AssetNameValidator.validateOwnerToken('MYTOKEN!')).to.be.true;
|
|
178
|
+
expect(AssetNameValidator.validateOwnerToken('$SECURITY!')).to.be.true;
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should reject names without ! suffix', () => {
|
|
182
|
+
expect(() => AssetNameValidator.validateOwnerToken('MYTOKEN'))
|
|
183
|
+
.to.throw(InvalidAssetNameError, 'must end with !');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
it('should reject invalid base names', () => {
|
|
187
|
+
expect(() => AssetNameValidator.validateOwnerToken('ab!'))
|
|
188
|
+
.to.throw(InvalidAssetNameError);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('validateAndDetectType', () => {
|
|
193
|
+
it('should detect and validate ROOT assets', () => {
|
|
194
|
+
const type = AssetNameValidator.validateAndDetectType('MYTOKEN');
|
|
195
|
+
expect(type).to.equal('ROOT');
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should detect and validate SUB assets', () => {
|
|
199
|
+
const type = AssetNameValidator.validateAndDetectType('MYTOKEN/SUB');
|
|
200
|
+
expect(type).to.equal('SUB');
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
it('should detect and validate UNIQUE assets', () => {
|
|
204
|
+
const type = AssetNameValidator.validateAndDetectType('MYTOKEN#NFT1');
|
|
205
|
+
expect(type).to.equal('UNIQUE');
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
it('should detect and validate QUALIFIER assets', () => {
|
|
209
|
+
const type = AssetNameValidator.validateAndDetectType('#KYC');
|
|
210
|
+
expect(type).to.equal('QUALIFIER');
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('should detect and validate SUB_QUALIFIER assets', () => {
|
|
214
|
+
const type = AssetNameValidator.validateAndDetectType('#KYC/TIER1');
|
|
215
|
+
expect(type).to.equal('SUB_QUALIFIER');
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it('should detect and validate RESTRICTED assets', () => {
|
|
219
|
+
const type = AssetNameValidator.validateAndDetectType('$SECURITY');
|
|
220
|
+
expect(type).to.equal('RESTRICTED');
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('should detect and validate OWNER tokens', () => {
|
|
224
|
+
const type = AssetNameValidator.validateAndDetectType('MYTOKEN!');
|
|
225
|
+
expect(type).to.equal('OWNER');
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
});
|