@neuraiproject/neurai-assets 1.2.3 → 1.2.5
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/dist/NeuraiAssets.global.js +244 -210
- package/dist/NeuraiAssets.global.js.map +1 -1
- package/dist/browser.js +244 -210
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +244 -210
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +244 -210
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1091,45 +1091,45 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1091
1091
|
};
|
|
1092
1092
|
|
|
1093
1093
|
/**
|
|
1094
|
-
* Asset naming
|
|
1094
|
+
* Asset naming helpers.
|
|
1095
|
+
* Network-specific maximum lengths are enforced in AssetNameValidator.
|
|
1095
1096
|
*/
|
|
1096
1097
|
const ASSET_NAME_RULES = {
|
|
1097
1098
|
ROOT: {
|
|
1098
1099
|
minLength: 3,
|
|
1099
|
-
maxLength:
|
|
1100
|
+
maxLength: 31,
|
|
1100
1101
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1101
|
-
|
|
1102
|
-
reserved: ['XNA', 'NEURAI']
|
|
1102
|
+
reserved: ['XNA', 'NEURAI', 'NEURAICOIN']
|
|
1103
1103
|
},
|
|
1104
1104
|
SUB: {
|
|
1105
1105
|
minLength: 1,
|
|
1106
|
-
maxLength:
|
|
1106
|
+
maxLength: 31,
|
|
1107
1107
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1108
1108
|
separator: '/',
|
|
1109
|
-
maxDepth:
|
|
1109
|
+
maxDepth: null
|
|
1110
1110
|
},
|
|
1111
1111
|
UNIQUE: {
|
|
1112
1112
|
minLength: 1,
|
|
1113
|
-
maxLength:
|
|
1114
|
-
pattern: /^[A-
|
|
1113
|
+
maxLength: 32,
|
|
1114
|
+
pattern: /^[-A-Za-z0-9@$%&*()[\]{}_.?:]+$/,
|
|
1115
1115
|
separator: '#'
|
|
1116
1116
|
},
|
|
1117
1117
|
QUALIFIER: {
|
|
1118
1118
|
minLength: 3,
|
|
1119
|
-
maxLength:
|
|
1120
|
-
pattern: /^[A-Z0-9_]+$/,
|
|
1119
|
+
maxLength: 32,
|
|
1120
|
+
pattern: /^[A-Z0-9_.]+$/,
|
|
1121
1121
|
prefix: '#',
|
|
1122
1122
|
separator: '/'
|
|
1123
1123
|
},
|
|
1124
1124
|
RESTRICTED: {
|
|
1125
1125
|
minLength: 3,
|
|
1126
|
-
maxLength:
|
|
1126
|
+
maxLength: 32,
|
|
1127
1127
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1128
1128
|
prefix: '$'
|
|
1129
1129
|
},
|
|
1130
1130
|
DEPIN: {
|
|
1131
1131
|
minLength: 3,
|
|
1132
|
-
maxLength:
|
|
1132
|
+
maxLength: 121,
|
|
1133
1133
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1134
1134
|
prefix: '&',
|
|
1135
1135
|
separator: '/'
|
|
@@ -3370,52 +3370,164 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3370
3370
|
const { ASSET_NAME_RULES } = requireConstants();
|
|
3371
3371
|
const { InvalidAssetNameError } = requireErrors();
|
|
3372
3372
|
|
|
3373
|
+
const MIN_ASSET_LENGTH = 3;
|
|
3374
|
+
const MAINNET_MAX_NAME_LENGTH = 32;
|
|
3375
|
+
const TESTNET_MAX_NAME_LENGTH = 121;
|
|
3376
|
+
|
|
3377
|
+
const ROOT_NAME_CHARACTERS = /^[A-Z0-9._]{3,}$/;
|
|
3378
|
+
const SUB_NAME_CHARACTERS = /^[A-Z0-9._]+$/;
|
|
3379
|
+
const UNIQUE_TAG_CHARACTERS = /^[-A-Za-z0-9@$%&*()[\]{}_.?:]+$/;
|
|
3380
|
+
const QUALIFIER_NAME_CHARACTERS = /^#[A-Z0-9._]{3,}$/;
|
|
3381
|
+
const SUB_QUALIFIER_NAME_CHARACTERS = /^#[A-Z0-9._]+$/;
|
|
3382
|
+
const RESTRICTED_NAME_CHARACTERS = /^\$[A-Z0-9._]{3,}$/;
|
|
3383
|
+
const DEPIN_NAME_CHARACTERS = /^&[A-Z0-9._]{3,}$/;
|
|
3384
|
+
const SUB_DEPIN_NAME_CHARACTERS = /^&[A-Z0-9._]+\/[A-Z0-9._/]+$/;
|
|
3385
|
+
const DOUBLE_PUNCTUATION = /^.*[._]{2,}.*$/;
|
|
3386
|
+
const LEADING_PUNCTUATION = /^[._].*$/;
|
|
3387
|
+
const TRAILING_PUNCTUATION = /^.*[._]$/;
|
|
3388
|
+
const QUALIFIER_LEADING_PUNCTUATION = /^[#$][._].*$/;
|
|
3389
|
+
const NEURAI_NAMES = /^XNA$|^NEURAI$|^NEURAICOIN$|^#XNA$|^#NEURAI$|^#NEURAICOIN$/;
|
|
3390
|
+
|
|
3391
|
+
function isTestnet(network) {
|
|
3392
|
+
return typeof network === 'string' && network.toLowerCase().includes('test');
|
|
3393
|
+
}
|
|
3394
|
+
|
|
3395
|
+
function getMaxAssetNameLength(network) {
|
|
3396
|
+
return isTestnet(network) ? TESTNET_MAX_NAME_LENGTH : MAINNET_MAX_NAME_LENGTH;
|
|
3397
|
+
}
|
|
3398
|
+
|
|
3399
|
+
function getRootOrSubMaxLength(network) {
|
|
3400
|
+
return getMaxAssetNameLength(network) - 1;
|
|
3401
|
+
}
|
|
3402
|
+
|
|
3403
|
+
function ensureName(name, label) {
|
|
3404
|
+
if (!name || typeof name !== 'string') {
|
|
3405
|
+
throw new InvalidAssetNameError(`${label} must be a non-empty string`, name);
|
|
3406
|
+
}
|
|
3407
|
+
}
|
|
3408
|
+
|
|
3409
|
+
function ensureMaxLength(name, maxLength, label) {
|
|
3410
|
+
if (name.length > maxLength) {
|
|
3411
|
+
throw new InvalidAssetNameError(`${label} cannot exceed ${maxLength} characters`, name);
|
|
3412
|
+
}
|
|
3413
|
+
}
|
|
3414
|
+
|
|
3415
|
+
function ensureUppercase(name, message) {
|
|
3416
|
+
if (name !== name.toUpperCase()) {
|
|
3417
|
+
throw new InvalidAssetNameError(message, name);
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3420
|
+
|
|
3421
|
+
function isRootNameValid(name) {
|
|
3422
|
+
return ROOT_NAME_CHARACTERS.test(name)
|
|
3423
|
+
&& !DOUBLE_PUNCTUATION.test(name)
|
|
3424
|
+
&& !LEADING_PUNCTUATION.test(name)
|
|
3425
|
+
&& !TRAILING_PUNCTUATION.test(name)
|
|
3426
|
+
&& !NEURAI_NAMES.test(name);
|
|
3427
|
+
}
|
|
3428
|
+
|
|
3429
|
+
function isSubNameValid(name) {
|
|
3430
|
+
return SUB_NAME_CHARACTERS.test(name)
|
|
3431
|
+
&& !DOUBLE_PUNCTUATION.test(name)
|
|
3432
|
+
&& !LEADING_PUNCTUATION.test(name)
|
|
3433
|
+
&& !TRAILING_PUNCTUATION.test(name);
|
|
3434
|
+
}
|
|
3435
|
+
|
|
3436
|
+
function isQualifierNameValid(name) {
|
|
3437
|
+
return QUALIFIER_NAME_CHARACTERS.test(name)
|
|
3438
|
+
&& !DOUBLE_PUNCTUATION.test(name)
|
|
3439
|
+
&& !QUALIFIER_LEADING_PUNCTUATION.test(name)
|
|
3440
|
+
&& !TRAILING_PUNCTUATION.test(name)
|
|
3441
|
+
&& !NEURAI_NAMES.test(name);
|
|
3442
|
+
}
|
|
3443
|
+
|
|
3444
|
+
function isSubQualifierNameValid(name) {
|
|
3445
|
+
return SUB_QUALIFIER_NAME_CHARACTERS.test(name)
|
|
3446
|
+
&& !DOUBLE_PUNCTUATION.test(name)
|
|
3447
|
+
&& !LEADING_PUNCTUATION.test(name)
|
|
3448
|
+
&& !TRAILING_PUNCTUATION.test(name);
|
|
3449
|
+
}
|
|
3450
|
+
|
|
3451
|
+
function isRestrictedNameValid(name) {
|
|
3452
|
+
return RESTRICTED_NAME_CHARACTERS.test(name)
|
|
3453
|
+
&& !DOUBLE_PUNCTUATION.test(name)
|
|
3454
|
+
&& !LEADING_PUNCTUATION.test(name)
|
|
3455
|
+
&& !TRAILING_PUNCTUATION.test(name)
|
|
3456
|
+
&& !NEURAI_NAMES.test(name);
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
function isNameValidBeforeTag(name) {
|
|
3460
|
+
const parts = name.split('/');
|
|
3461
|
+
|
|
3462
|
+
if (!isRootNameValid(parts[0])) {
|
|
3463
|
+
return false;
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
for (let index = 1; index < parts.length; index += 1) {
|
|
3467
|
+
if (!isSubNameValid(parts[index])) {
|
|
3468
|
+
return false;
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3472
|
+
return true;
|
|
3473
|
+
}
|
|
3474
|
+
|
|
3475
|
+
function isQualifierNameValidBeforeTag(name) {
|
|
3476
|
+
const parts = name.split('/');
|
|
3477
|
+
|
|
3478
|
+
if (!isQualifierNameValid(parts[0])) {
|
|
3479
|
+
return false;
|
|
3480
|
+
}
|
|
3481
|
+
|
|
3482
|
+
if (parts.length > 2) {
|
|
3483
|
+
return false;
|
|
3484
|
+
}
|
|
3485
|
+
|
|
3486
|
+
for (let index = 1; index < parts.length; index += 1) {
|
|
3487
|
+
if (!isSubQualifierNameValid(parts[index])) {
|
|
3488
|
+
return false;
|
|
3489
|
+
}
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
return true;
|
|
3493
|
+
}
|
|
3494
|
+
|
|
3495
|
+
function isDepinIndicator(name) {
|
|
3496
|
+
return DEPIN_NAME_CHARACTERS.test(name) || SUB_DEPIN_NAME_CHARACTERS.test(name);
|
|
3497
|
+
}
|
|
3498
|
+
|
|
3373
3499
|
class AssetNameValidator {
|
|
3374
3500
|
/**
|
|
3375
3501
|
* Validate ROOT asset name
|
|
3376
|
-
* Rules: 3-
|
|
3377
|
-
* Cannot start with period,
|
|
3502
|
+
* Rules: 3-31 visible characters on mainnet, A-Z, 0-9, underscore, period
|
|
3503
|
+
* Cannot start or end with period/underscore, cannot use repeated punctuation
|
|
3378
3504
|
* Cannot be reserved names
|
|
3379
3505
|
*/
|
|
3380
|
-
static validateRoot(name) {
|
|
3381
|
-
|
|
3382
|
-
|
|
3383
|
-
|
|
3506
|
+
static validateRoot(name, network = 'xna') {
|
|
3507
|
+
ensureName(name, 'Asset name');
|
|
3508
|
+
|
|
3509
|
+
const maxLength = getRootOrSubMaxLength(network);
|
|
3384
3510
|
|
|
3385
|
-
|
|
3386
|
-
if (name.length < ASSET_NAME_RULES.ROOT.minLength || name.length > ASSET_NAME_RULES.ROOT.maxLength) {
|
|
3511
|
+
if (name.length < MIN_ASSET_LENGTH || name.length > maxLength) {
|
|
3387
3512
|
throw new InvalidAssetNameError(
|
|
3388
|
-
`ROOT asset name must be ${
|
|
3513
|
+
`ROOT asset name must be ${MIN_ASSET_LENGTH}-${maxLength} characters`,
|
|
3389
3514
|
name
|
|
3390
3515
|
);
|
|
3391
3516
|
}
|
|
3392
3517
|
|
|
3393
|
-
|
|
3394
|
-
if (name !== name.toUpperCase()) {
|
|
3395
|
-
throw new InvalidAssetNameError('Asset name must be uppercase', name);
|
|
3396
|
-
}
|
|
3518
|
+
ensureUppercase(name, 'Asset name must be uppercase');
|
|
3397
3519
|
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
throw new InvalidAssetNameError(
|
|
3401
|
-
`Asset name cannot start with: ${ASSET_NAME_RULES.ROOT.cannotStartWith.join(', ')}`,
|
|
3402
|
-
name
|
|
3403
|
-
);
|
|
3520
|
+
if (NEURAI_NAMES.test(name)) {
|
|
3521
|
+
throw new InvalidAssetNameError(`${name} is a reserved asset name`, name);
|
|
3404
3522
|
}
|
|
3405
3523
|
|
|
3406
|
-
|
|
3407
|
-
if (!ASSET_NAME_RULES.ROOT.pattern.test(name)) {
|
|
3524
|
+
if (!isRootNameValid(name)) {
|
|
3408
3525
|
throw new InvalidAssetNameError(
|
|
3409
|
-
'
|
|
3526
|
+
'Name contains invalid characters (Valid characters are: A-Z 0-9 _ .) (special characters can\'t be the first or last characters)',
|
|
3410
3527
|
name
|
|
3411
3528
|
);
|
|
3412
3529
|
}
|
|
3413
3530
|
|
|
3414
|
-
// Reserved names check
|
|
3415
|
-
if (ASSET_NAME_RULES.ROOT.reserved.includes(name)) {
|
|
3416
|
-
throw new InvalidAssetNameError(`${name} is a reserved asset name`, name);
|
|
3417
|
-
}
|
|
3418
|
-
|
|
3419
3531
|
return true;
|
|
3420
3532
|
}
|
|
3421
3533
|
|
|
@@ -3423,39 +3535,25 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3423
3535
|
* Validate SUB asset name
|
|
3424
3536
|
* Format: ROOT/SUBNAME
|
|
3425
3537
|
*/
|
|
3426
|
-
static validateSub(name) {
|
|
3427
|
-
|
|
3428
|
-
throw new InvalidAssetNameError('SUB asset name must be a non-empty string', name);
|
|
3429
|
-
}
|
|
3538
|
+
static validateSub(name, network = 'xna') {
|
|
3539
|
+
ensureName(name, 'SUB asset name');
|
|
3430
3540
|
|
|
3431
|
-
|
|
3432
|
-
if (parts.length !== 2) {
|
|
3541
|
+
if (!name.includes(ASSET_NAME_RULES.SUB.separator)) {
|
|
3433
3542
|
throw new InvalidAssetNameError(
|
|
3434
3543
|
`SUB asset must be in ${ASSET_NAME_RULES.SUB.separator} format (ROOT/SUBNAME)`,
|
|
3435
3544
|
name
|
|
3436
3545
|
);
|
|
3437
3546
|
}
|
|
3438
3547
|
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
// Validate root part
|
|
3442
|
-
this.validateRoot(rootName);
|
|
3443
|
-
|
|
3444
|
-
// Validate sub part
|
|
3445
|
-
if (subName.length < ASSET_NAME_RULES.SUB.minLength || subName.length > ASSET_NAME_RULES.SUB.maxLength) {
|
|
3446
|
-
throw new InvalidAssetNameError(
|
|
3447
|
-
`SUB asset name must be ${ASSET_NAME_RULES.SUB.minLength}-${ASSET_NAME_RULES.SUB.maxLength} characters`,
|
|
3448
|
-
name
|
|
3449
|
-
);
|
|
3450
|
-
}
|
|
3548
|
+
ensureMaxLength(name, getRootOrSubMaxLength(network), 'SUB asset name');
|
|
3451
3549
|
|
|
3452
|
-
if (
|
|
3550
|
+
if (name !== name.toUpperCase()) {
|
|
3453
3551
|
throw new InvalidAssetNameError('SUB asset name must be uppercase', name);
|
|
3454
3552
|
}
|
|
3455
3553
|
|
|
3456
|
-
if (!
|
|
3554
|
+
if (!isNameValidBeforeTag(name)) {
|
|
3457
3555
|
throw new InvalidAssetNameError(
|
|
3458
|
-
'
|
|
3556
|
+
'Name contains invalid characters (Valid characters are: A-Z 0-9 _ .) (special characters can\'t be the first or last characters)',
|
|
3459
3557
|
name
|
|
3460
3558
|
);
|
|
3461
3559
|
}
|
|
@@ -3467,10 +3565,10 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3467
3565
|
* Validate UNIQUE asset name
|
|
3468
3566
|
* Format: ROOT#TAG
|
|
3469
3567
|
*/
|
|
3470
|
-
static validateUnique(name) {
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3568
|
+
static validateUnique(name, network = 'xna') {
|
|
3569
|
+
ensureName(name, 'UNIQUE asset name');
|
|
3570
|
+
|
|
3571
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'UNIQUE asset name');
|
|
3474
3572
|
|
|
3475
3573
|
const parts = name.split(ASSET_NAME_RULES.UNIQUE.separator);
|
|
3476
3574
|
if (parts.length !== 2) {
|
|
@@ -3482,24 +3580,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3482
3580
|
|
|
3483
3581
|
const [rootName, tag] = parts;
|
|
3484
3582
|
|
|
3485
|
-
|
|
3486
|
-
this.validateRoot(rootName);
|
|
3487
|
-
|
|
3488
|
-
// Validate tag
|
|
3489
|
-
if (tag.length < ASSET_NAME_RULES.UNIQUE.minLength || tag.length > ASSET_NAME_RULES.UNIQUE.maxLength) {
|
|
3490
|
-
throw new InvalidAssetNameError(
|
|
3491
|
-
`UNIQUE tag must be ${ASSET_NAME_RULES.UNIQUE.minLength}-${ASSET_NAME_RULES.UNIQUE.maxLength} characters`,
|
|
3492
|
-
name
|
|
3493
|
-
);
|
|
3494
|
-
}
|
|
3495
|
-
|
|
3496
|
-
if (tag !== tag.toUpperCase()) {
|
|
3497
|
-
throw new InvalidAssetNameError('UNIQUE tag must be uppercase', name);
|
|
3498
|
-
}
|
|
3499
|
-
|
|
3500
|
-
if (!ASSET_NAME_RULES.UNIQUE.pattern.test(tag)) {
|
|
3583
|
+
if (!isNameValidBeforeTag(rootName) || !UNIQUE_TAG_CHARACTERS.test(tag)) {
|
|
3501
3584
|
throw new InvalidAssetNameError(
|
|
3502
|
-
'
|
|
3585
|
+
'Unique name contains invalid characters (Valid characters are: A-Z a-z 0-9 @ $ % & * ( ) [ ] { } _ . ? : -)',
|
|
3503
3586
|
name
|
|
3504
3587
|
);
|
|
3505
3588
|
}
|
|
@@ -3511,10 +3594,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3511
3594
|
* Validate QUALIFIER asset name
|
|
3512
3595
|
* Format: #NAME or #ROOT/SUB
|
|
3513
3596
|
*/
|
|
3514
|
-
static validateQualifier(name) {
|
|
3515
|
-
|
|
3516
|
-
throw new InvalidAssetNameError('QUALIFIER asset name must be a non-empty string', name);
|
|
3517
|
-
}
|
|
3597
|
+
static validateQualifier(name, network = 'xna') {
|
|
3598
|
+
ensureName(name, 'QUALIFIER asset name');
|
|
3518
3599
|
|
|
3519
3600
|
if (!name.startsWith(ASSET_NAME_RULES.QUALIFIER.prefix)) {
|
|
3520
3601
|
throw new InvalidAssetNameError(
|
|
@@ -3523,58 +3604,17 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3523
3604
|
);
|
|
3524
3605
|
}
|
|
3525
3606
|
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
if (withoutPrefix.includes(ASSET_NAME_RULES.QUALIFIER.separator)) {
|
|
3529
|
-
// Sub-qualifier: #ROOT/SUB
|
|
3530
|
-
const parts = withoutPrefix.split(ASSET_NAME_RULES.QUALIFIER.separator);
|
|
3531
|
-
if (parts.length !== 2) {
|
|
3532
|
-
throw new InvalidAssetNameError(
|
|
3533
|
-
'SUB_QUALIFIER must be in #ROOT/SUB format',
|
|
3534
|
-
name
|
|
3535
|
-
);
|
|
3536
|
-
}
|
|
3607
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'QUALIFIER asset name');
|
|
3537
3608
|
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
throw new InvalidAssetNameError(
|
|
3542
|
-
`QUALIFIER name must be ${ASSET_NAME_RULES.QUALIFIER.minLength}-${ASSET_NAME_RULES.QUALIFIER.maxLength} characters`,
|
|
3543
|
-
name
|
|
3544
|
-
);
|
|
3545
|
-
}
|
|
3546
|
-
|
|
3547
|
-
if (part !== part.toUpperCase()) {
|
|
3548
|
-
throw new InvalidAssetNameError('QUALIFIER name must be uppercase', name);
|
|
3549
|
-
}
|
|
3550
|
-
|
|
3551
|
-
if (!ASSET_NAME_RULES.QUALIFIER.pattern.test(part)) {
|
|
3552
|
-
throw new InvalidAssetNameError(
|
|
3553
|
-
'QUALIFIER name can only contain A-Z, 0-9, and underscore',
|
|
3554
|
-
name
|
|
3555
|
-
);
|
|
3556
|
-
}
|
|
3557
|
-
});
|
|
3558
|
-
} else {
|
|
3559
|
-
// Root qualifier: #NAME
|
|
3560
|
-
if (withoutPrefix.length < ASSET_NAME_RULES.QUALIFIER.minLength ||
|
|
3561
|
-
withoutPrefix.length > ASSET_NAME_RULES.QUALIFIER.maxLength) {
|
|
3562
|
-
throw new InvalidAssetNameError(
|
|
3563
|
-
`QUALIFIER name must be ${ASSET_NAME_RULES.QUALIFIER.minLength}-${ASSET_NAME_RULES.QUALIFIER.maxLength} characters`,
|
|
3564
|
-
name
|
|
3565
|
-
);
|
|
3566
|
-
}
|
|
3567
|
-
|
|
3568
|
-
if (withoutPrefix !== withoutPrefix.toUpperCase()) {
|
|
3569
|
-
throw new InvalidAssetNameError('QUALIFIER name must be uppercase', name);
|
|
3570
|
-
}
|
|
3609
|
+
if (name !== name.toUpperCase()) {
|
|
3610
|
+
throw new InvalidAssetNameError('QUALIFIER name must be uppercase', name);
|
|
3611
|
+
}
|
|
3571
3612
|
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
}
|
|
3613
|
+
if (!isQualifierNameValidBeforeTag(name)) {
|
|
3614
|
+
throw new InvalidAssetNameError(
|
|
3615
|
+
'Qualifier name contains invalid characters (Valid characters are: A-Z 0-9 _ .) (# must be the first character, _ . special characters can\'t be the first or last characters)',
|
|
3616
|
+
name
|
|
3617
|
+
);
|
|
3578
3618
|
}
|
|
3579
3619
|
|
|
3580
3620
|
return true;
|
|
@@ -3584,10 +3624,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3584
3624
|
* Validate RESTRICTED asset name
|
|
3585
3625
|
* Format: $NAME
|
|
3586
3626
|
*/
|
|
3587
|
-
static validateRestricted(name) {
|
|
3588
|
-
|
|
3589
|
-
throw new InvalidAssetNameError('RESTRICTED asset name must be a non-empty string', name);
|
|
3590
|
-
}
|
|
3627
|
+
static validateRestricted(name, network = 'xna') {
|
|
3628
|
+
ensureName(name, 'RESTRICTED asset name');
|
|
3591
3629
|
|
|
3592
3630
|
if (!name.startsWith(ASSET_NAME_RULES.RESTRICTED.prefix)) {
|
|
3593
3631
|
throw new InvalidAssetNameError(
|
|
@@ -3596,10 +3634,18 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3596
3634
|
);
|
|
3597
3635
|
}
|
|
3598
3636
|
|
|
3599
|
-
|
|
3637
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'RESTRICTED asset name');
|
|
3600
3638
|
|
|
3601
|
-
|
|
3602
|
-
|
|
3639
|
+
if (name !== name.toUpperCase()) {
|
|
3640
|
+
throw new InvalidAssetNameError('RESTRICTED asset name must be uppercase', name);
|
|
3641
|
+
}
|
|
3642
|
+
|
|
3643
|
+
if (!isRestrictedNameValid(name)) {
|
|
3644
|
+
throw new InvalidAssetNameError(
|
|
3645
|
+
'Restricted name contains invalid characters (Valid characters are: A-Z 0-9 _ .) ($ must be the first character, _ . special characters can\'t be the first or last characters)',
|
|
3646
|
+
name
|
|
3647
|
+
);
|
|
3648
|
+
}
|
|
3603
3649
|
|
|
3604
3650
|
return true;
|
|
3605
3651
|
}
|
|
@@ -3608,10 +3654,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3608
3654
|
* Validate DEPIN asset name
|
|
3609
3655
|
* Format: &NAME or &NAME/SUB[/...]
|
|
3610
3656
|
*/
|
|
3611
|
-
static validateDepin(name) {
|
|
3612
|
-
|
|
3613
|
-
throw new InvalidAssetNameError('DEPIN asset name must be a non-empty string', name);
|
|
3614
|
-
}
|
|
3657
|
+
static validateDepin(name, network) {
|
|
3658
|
+
ensureName(name, 'DEPIN asset name');
|
|
3615
3659
|
|
|
3616
3660
|
if (!name.startsWith(ASSET_NAME_RULES.DEPIN.prefix)) {
|
|
3617
3661
|
throw new InvalidAssetNameError(
|
|
@@ -3620,58 +3664,41 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3620
3664
|
);
|
|
3621
3665
|
}
|
|
3622
3666
|
|
|
3623
|
-
if (
|
|
3624
|
-
throw new InvalidAssetNameError(
|
|
3625
|
-
`DEPIN asset name cannot exceed ${ASSET_NAME_RULES.DEPIN.maxLength} characters`,
|
|
3626
|
-
name
|
|
3627
|
-
);
|
|
3667
|
+
if (network && !isTestnet(network)) {
|
|
3668
|
+
throw new InvalidAssetNameError('DEPIN assets are only available in testnet', name);
|
|
3628
3669
|
}
|
|
3629
3670
|
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3671
|
+
ensureMaxLength(name, getMaxAssetNameLength(network || 'xna-test'), 'DEPIN asset name');
|
|
3672
|
+
|
|
3673
|
+
if (name !== name.toUpperCase()) {
|
|
3674
|
+
throw new InvalidAssetNameError('DEPIN asset name must be uppercase', name);
|
|
3633
3675
|
}
|
|
3634
3676
|
|
|
3635
|
-
|
|
3636
|
-
if (rootPart.length < ASSET_NAME_RULES.DEPIN.minLength) {
|
|
3677
|
+
if (!isDepinIndicator(name)) {
|
|
3637
3678
|
throw new InvalidAssetNameError(
|
|
3638
|
-
|
|
3679
|
+
'DEPIN asset name can only contain A-Z, 0-9, underscore, period, and separator /',
|
|
3639
3680
|
name
|
|
3640
3681
|
);
|
|
3641
3682
|
}
|
|
3642
3683
|
|
|
3643
|
-
|
|
3644
|
-
throw new InvalidAssetNameError('DEPIN asset name must be uppercase', name);
|
|
3645
|
-
}
|
|
3684
|
+
const parts = name.split(ASSET_NAME_RULES.DEPIN.separator);
|
|
3646
3685
|
|
|
3647
|
-
if (
|
|
3686
|
+
if (parts.length > 1) {
|
|
3687
|
+
parts.forEach(part => {
|
|
3688
|
+
if (part.length < MIN_ASSET_LENGTH) {
|
|
3689
|
+
throw new InvalidAssetNameError(
|
|
3690
|
+
`Each DEPIN sub-part must be at least ${MIN_ASSET_LENGTH} characters`,
|
|
3691
|
+
name
|
|
3692
|
+
);
|
|
3693
|
+
}
|
|
3694
|
+
});
|
|
3695
|
+
} else if (name.length < MIN_ASSET_LENGTH + 1) {
|
|
3648
3696
|
throw new InvalidAssetNameError(
|
|
3649
|
-
|
|
3697
|
+
`DEPIN name must be at least ${MIN_ASSET_LENGTH} characters (excluding &)`,
|
|
3650
3698
|
name
|
|
3651
3699
|
);
|
|
3652
3700
|
}
|
|
3653
3701
|
|
|
3654
|
-
const subParts = parts.slice(1);
|
|
3655
|
-
subParts.forEach(part => {
|
|
3656
|
-
if (part.length < ASSET_NAME_RULES.DEPIN.minLength) {
|
|
3657
|
-
throw new InvalidAssetNameError(
|
|
3658
|
-
`Each DEPIN sub-part must be at least ${ASSET_NAME_RULES.DEPIN.minLength} characters`,
|
|
3659
|
-
name
|
|
3660
|
-
);
|
|
3661
|
-
}
|
|
3662
|
-
|
|
3663
|
-
if (part !== part.toUpperCase()) {
|
|
3664
|
-
throw new InvalidAssetNameError('DEPIN asset name must be uppercase', name);
|
|
3665
|
-
}
|
|
3666
|
-
|
|
3667
|
-
if (!ASSET_NAME_RULES.DEPIN.pattern.test(part)) {
|
|
3668
|
-
throw new InvalidAssetNameError(
|
|
3669
|
-
'DEPIN asset name can only contain A-Z, 0-9, underscore, and period',
|
|
3670
|
-
name
|
|
3671
|
-
);
|
|
3672
|
-
}
|
|
3673
|
-
});
|
|
3674
|
-
|
|
3675
3702
|
return true;
|
|
3676
3703
|
}
|
|
3677
3704
|
|
|
@@ -3679,24 +3706,31 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3679
3706
|
* Validate owner token name
|
|
3680
3707
|
* Format: ASSETNAME!
|
|
3681
3708
|
*/
|
|
3682
|
-
static validateOwnerToken(name) {
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3709
|
+
static validateOwnerToken(name, network) {
|
|
3710
|
+
ensureName(name, 'Owner token name');
|
|
3711
|
+
|
|
3712
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'Owner token name');
|
|
3686
3713
|
|
|
3687
3714
|
if (!name.endsWith('!')) {
|
|
3688
3715
|
throw new InvalidAssetNameError('Owner token must end with !', name);
|
|
3689
3716
|
}
|
|
3690
3717
|
|
|
3691
3718
|
const assetName = name.substring(0, name.length - 1);
|
|
3719
|
+
const validBaseName = isNameValidBeforeTag(assetName)
|
|
3720
|
+
|| (assetName.startsWith('&') && (() => {
|
|
3721
|
+
try {
|
|
3722
|
+
this.validateDepin(assetName, network);
|
|
3723
|
+
return true;
|
|
3724
|
+
} catch (error) {
|
|
3725
|
+
return false;
|
|
3726
|
+
}
|
|
3727
|
+
})());
|
|
3692
3728
|
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
} else {
|
|
3699
|
-
this.validateRoot(assetName);
|
|
3729
|
+
if (!validBaseName) {
|
|
3730
|
+
throw new InvalidAssetNameError(
|
|
3731
|
+
'Owner name contains invalid characters (Valid characters are: A-Z 0-9 _ .) (special characters can\'t be the first or last characters)',
|
|
3732
|
+
name
|
|
3733
|
+
);
|
|
3700
3734
|
}
|
|
3701
3735
|
|
|
3702
3736
|
return true;
|
|
@@ -3707,27 +3741,27 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3707
3741
|
* @param {string} name - Asset name
|
|
3708
3742
|
* @returns {string} Asset type ('ROOT', 'SUB', 'UNIQUE', 'QUALIFIER', 'RESTRICTED', 'DEPIN', 'OWNER')
|
|
3709
3743
|
*/
|
|
3710
|
-
static validateAndDetectType(name) {
|
|
3744
|
+
static validateAndDetectType(name, network) {
|
|
3711
3745
|
if (name.endsWith('!')) {
|
|
3712
|
-
this.validateOwnerToken(name);
|
|
3746
|
+
this.validateOwnerToken(name, network);
|
|
3713
3747
|
return 'OWNER';
|
|
3714
3748
|
} else if (name.startsWith('#')) {
|
|
3715
|
-
this.validateQualifier(name);
|
|
3749
|
+
this.validateQualifier(name, network);
|
|
3716
3750
|
return name.includes('/') ? 'SUB_QUALIFIER' : 'QUALIFIER';
|
|
3717
3751
|
} else if (name.startsWith('$')) {
|
|
3718
|
-
this.validateRestricted(name);
|
|
3752
|
+
this.validateRestricted(name, network);
|
|
3719
3753
|
return 'RESTRICTED';
|
|
3720
3754
|
} else if (name.startsWith('&')) {
|
|
3721
|
-
this.validateDepin(name);
|
|
3755
|
+
this.validateDepin(name, network);
|
|
3722
3756
|
return 'DEPIN';
|
|
3723
3757
|
} else if (name.includes('#')) {
|
|
3724
|
-
this.validateUnique(name);
|
|
3758
|
+
this.validateUnique(name, network);
|
|
3725
3759
|
return 'UNIQUE';
|
|
3726
3760
|
} else if (name.includes('/')) {
|
|
3727
|
-
this.validateSub(name);
|
|
3761
|
+
this.validateSub(name, network);
|
|
3728
3762
|
return 'SUB';
|
|
3729
3763
|
} else {
|
|
3730
|
-
this.validateRoot(name);
|
|
3764
|
+
this.validateRoot(name, network);
|
|
3731
3765
|
return 'ROOT';
|
|
3732
3766
|
}
|
|
3733
3767
|
}
|
|
@@ -4404,22 +4438,22 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4404
4438
|
|
|
4405
4439
|
switch (type) {
|
|
4406
4440
|
case 'ROOT':
|
|
4407
|
-
AssetNameValidator.validateRoot(assetName);
|
|
4441
|
+
AssetNameValidator.validateRoot(assetName, this.network);
|
|
4408
4442
|
break;
|
|
4409
4443
|
case 'SUB':
|
|
4410
|
-
AssetNameValidator.validateSub(assetName);
|
|
4444
|
+
AssetNameValidator.validateSub(assetName, this.network);
|
|
4411
4445
|
break;
|
|
4412
4446
|
case 'UNIQUE':
|
|
4413
|
-
AssetNameValidator.validateUnique(assetName);
|
|
4447
|
+
AssetNameValidator.validateUnique(assetName, this.network);
|
|
4414
4448
|
break;
|
|
4415
4449
|
case 'QUALIFIER':
|
|
4416
|
-
AssetNameValidator.validateQualifier(assetName);
|
|
4450
|
+
AssetNameValidator.validateQualifier(assetName, this.network);
|
|
4417
4451
|
break;
|
|
4418
4452
|
case 'RESTRICTED':
|
|
4419
|
-
AssetNameValidator.validateRestricted(assetName);
|
|
4453
|
+
AssetNameValidator.validateRestricted(assetName, this.network);
|
|
4420
4454
|
break;
|
|
4421
4455
|
case 'DEPIN':
|
|
4422
|
-
AssetNameValidator.validateDepin(assetName);
|
|
4456
|
+
AssetNameValidator.validateDepin(assetName, this.network);
|
|
4423
4457
|
break;
|
|
4424
4458
|
default:
|
|
4425
4459
|
throw new Error(`Unknown asset type: ${type}`);
|
|
@@ -5840,7 +5874,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5840
5874
|
*
|
|
5841
5875
|
* QUALIFIER assets:
|
|
5842
5876
|
* - KYC/compliance tags (e.g., #KYC_VERIFIED, #ACCREDITED)
|
|
5843
|
-
* - Format: #NAME or #ROOT
|
|
5877
|
+
* - Format: #NAME or #ROOT/#SUB
|
|
5844
5878
|
* - Cost: 2000 XNA (root) or 200 XNA (sub-qualifier)
|
|
5845
5879
|
* - Quantity: 1-10 units only
|
|
5846
5880
|
* - Units: Always 0 (non-divisible)
|
|
@@ -7305,7 +7339,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
7305
7339
|
/**
|
|
7306
7340
|
* Create a ROOT asset
|
|
7307
7341
|
* @param {object} params - Asset creation parameters
|
|
7308
|
-
|
|
7342
|
+
* @param {string} params.assetName - Asset name (3-31 visible chars on mainnet, A-Z 0-9 _ .)
|
|
7309
7343
|
* @param {number} params.quantity - Total supply
|
|
7310
7344
|
* @param {number} [params.units=0] - Decimal places (0-8)
|
|
7311
7345
|
* @param {boolean} [params.reissuable=true] - Can mint more later
|