@neuraiproject/neurai-assets 1.2.2 → 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/README.md +21 -21
- package/dist/NeuraiAssets.global.js +329 -235
- package/dist/NeuraiAssets.global.js.map +1 -1
- package/dist/browser.js +329 -235
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +329 -235
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +329 -235
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -1040,11 +1040,15 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1040
1040
|
function requireNetworks () {
|
|
1041
1041
|
if (hasRequiredNetworks) return networks;
|
|
1042
1042
|
hasRequiredNetworks = 1;
|
|
1043
|
+
const MAINNET_NETWORKS = ['xna', 'mainnet', 'xna-pq', 'mainnet-pq'];
|
|
1044
|
+
const TESTNET_NETWORKS = ['xna-test', 'testnet', 'regtest', 'xna-pq-test', 'testnet-pq'];
|
|
1045
|
+
|
|
1043
1046
|
const NETWORKS = {
|
|
1044
1047
|
MAINNET: {
|
|
1045
1048
|
name: 'xna',
|
|
1046
1049
|
displayName: 'Neurai Mainnet',
|
|
1047
1050
|
addressPrefix: 'N',
|
|
1051
|
+
authScriptAddressPrefix: 'nq1',
|
|
1048
1052
|
pqAddressPrefix: 'nq1',
|
|
1049
1053
|
assetNameMaxLength: 32,
|
|
1050
1054
|
defaultRPCPort: 19001,
|
|
@@ -1055,6 +1059,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1055
1059
|
name: 'xna-test',
|
|
1056
1060
|
displayName: 'Neurai Testnet',
|
|
1057
1061
|
addressPrefix: 't',
|
|
1062
|
+
authScriptAddressPrefix: 'tnq1',
|
|
1058
1063
|
pqAddressPrefix: 'tnq1',
|
|
1059
1064
|
assetNameMaxLength: 32, // Same as mainnet
|
|
1060
1065
|
defaultRPCPort: 19101,
|
|
@@ -1063,8 +1068,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1063
1068
|
},
|
|
1064
1069
|
MAINNET_PQ: {
|
|
1065
1070
|
name: 'xna-pq',
|
|
1066
|
-
displayName: 'Neurai Mainnet
|
|
1071
|
+
displayName: 'Neurai Mainnet AuthScript',
|
|
1067
1072
|
addressPrefix: 'N',
|
|
1073
|
+
authScriptAddressPrefix: 'nq1',
|
|
1068
1074
|
pqAddressPrefix: 'nq1',
|
|
1069
1075
|
assetNameMaxLength: 32,
|
|
1070
1076
|
defaultRPCPort: 19001,
|
|
@@ -1073,8 +1079,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1073
1079
|
},
|
|
1074
1080
|
TESTNET_PQ: {
|
|
1075
1081
|
name: 'xna-pq-test',
|
|
1076
|
-
displayName: 'Neurai Testnet
|
|
1082
|
+
displayName: 'Neurai Testnet AuthScript',
|
|
1077
1083
|
addressPrefix: 't',
|
|
1084
|
+
authScriptAddressPrefix: 'tnq1',
|
|
1078
1085
|
pqAddressPrefix: 'tnq1',
|
|
1079
1086
|
assetNameMaxLength: 32,
|
|
1080
1087
|
defaultRPCPort: 19101,
|
|
@@ -1084,45 +1091,45 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1084
1091
|
};
|
|
1085
1092
|
|
|
1086
1093
|
/**
|
|
1087
|
-
* Asset naming
|
|
1094
|
+
* Asset naming helpers.
|
|
1095
|
+
* Network-specific maximum lengths are enforced in AssetNameValidator.
|
|
1088
1096
|
*/
|
|
1089
1097
|
const ASSET_NAME_RULES = {
|
|
1090
1098
|
ROOT: {
|
|
1091
1099
|
minLength: 3,
|
|
1092
|
-
maxLength:
|
|
1100
|
+
maxLength: 31,
|
|
1093
1101
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1094
|
-
|
|
1095
|
-
reserved: ['XNA', 'NEURAI']
|
|
1102
|
+
reserved: ['XNA', 'NEURAI', 'NEURAICOIN']
|
|
1096
1103
|
},
|
|
1097
1104
|
SUB: {
|
|
1098
1105
|
minLength: 1,
|
|
1099
|
-
maxLength:
|
|
1106
|
+
maxLength: 31,
|
|
1100
1107
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1101
1108
|
separator: '/',
|
|
1102
|
-
maxDepth:
|
|
1109
|
+
maxDepth: null
|
|
1103
1110
|
},
|
|
1104
1111
|
UNIQUE: {
|
|
1105
1112
|
minLength: 1,
|
|
1106
|
-
maxLength:
|
|
1107
|
-
pattern: /^[A-
|
|
1113
|
+
maxLength: 32,
|
|
1114
|
+
pattern: /^[-A-Za-z0-9@$%&*()[\]{}_.?:]+$/,
|
|
1108
1115
|
separator: '#'
|
|
1109
1116
|
},
|
|
1110
1117
|
QUALIFIER: {
|
|
1111
1118
|
minLength: 3,
|
|
1112
|
-
maxLength:
|
|
1113
|
-
pattern: /^[A-Z0-9_]+$/,
|
|
1119
|
+
maxLength: 32,
|
|
1120
|
+
pattern: /^[A-Z0-9_.]+$/,
|
|
1114
1121
|
prefix: '#',
|
|
1115
1122
|
separator: '/'
|
|
1116
1123
|
},
|
|
1117
1124
|
RESTRICTED: {
|
|
1118
1125
|
minLength: 3,
|
|
1119
|
-
maxLength:
|
|
1126
|
+
maxLength: 32,
|
|
1120
1127
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1121
1128
|
prefix: '$'
|
|
1122
1129
|
},
|
|
1123
1130
|
DEPIN: {
|
|
1124
1131
|
minLength: 3,
|
|
1125
|
-
maxLength:
|
|
1132
|
+
maxLength: 121,
|
|
1126
1133
|
pattern: /^[A-Z0-9_.]+$/,
|
|
1127
1134
|
prefix: '&',
|
|
1128
1135
|
separator: '/'
|
|
@@ -1144,32 +1151,68 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1144
1151
|
|
|
1145
1152
|
/**
|
|
1146
1153
|
* Get network configuration
|
|
1154
|
+
* `xna-pq` / `xna-pq-test` are preserved as compatibility aliases for
|
|
1155
|
+
* AuthScript address flows on the same mainnet/testnet families.
|
|
1156
|
+
*
|
|
1147
1157
|
* @param {string} networkName - Network name ('xna', 'xna-test', 'xna-pq', or 'xna-pq-test')
|
|
1148
1158
|
* @returns {object} Network configuration
|
|
1149
1159
|
*/
|
|
1150
1160
|
function getNetworkConfig(networkName) {
|
|
1151
|
-
if (networkName
|
|
1152
|
-
return
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
} else if (networkName
|
|
1156
|
-
return
|
|
1157
|
-
|
|
1158
|
-
|
|
1161
|
+
if (MAINNET_NETWORKS.includes(networkName)) {
|
|
1162
|
+
return networkName === 'xna-pq' || networkName === 'mainnet-pq'
|
|
1163
|
+
? NETWORKS.MAINNET_PQ
|
|
1164
|
+
: NETWORKS.MAINNET;
|
|
1165
|
+
} else if (TESTNET_NETWORKS.includes(networkName)) {
|
|
1166
|
+
return networkName === 'xna-pq-test' || networkName === 'testnet-pq'
|
|
1167
|
+
? NETWORKS.TESTNET_PQ
|
|
1168
|
+
: NETWORKS.TESTNET;
|
|
1159
1169
|
} else {
|
|
1160
1170
|
throw new Error(`Unknown network: ${networkName}`);
|
|
1161
1171
|
}
|
|
1162
1172
|
}
|
|
1163
1173
|
|
|
1164
1174
|
/**
|
|
1165
|
-
*
|
|
1175
|
+
* Resolve a network name to its chain family.
|
|
1176
|
+
* AuthScript aliases share the same family as legacy addresses.
|
|
1177
|
+
*
|
|
1178
|
+
* @param {string} networkName - Network name
|
|
1179
|
+
* @returns {'mainnet'|'testnet'} Network family
|
|
1180
|
+
*/
|
|
1181
|
+
function resolveAddressNetworkFamily(networkName) {
|
|
1182
|
+
if (MAINNET_NETWORKS.includes(networkName)) {
|
|
1183
|
+
return 'mainnet';
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
if (TESTNET_NETWORKS.includes(networkName)) {
|
|
1187
|
+
return 'testnet';
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
throw new Error(`Unknown network: ${networkName}`);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* Determine whether two network labels are compatible for address use.
|
|
1195
|
+
* This treats legacy and AuthScript labels on the same chain as compatible.
|
|
1196
|
+
*
|
|
1197
|
+
* @param {string} left - First network name
|
|
1198
|
+
* @param {string} right - Second network name
|
|
1199
|
+
* @returns {boolean} True if both belong to the same chain family
|
|
1200
|
+
*/
|
|
1201
|
+
function areAddressNetworksCompatible(left, right) {
|
|
1202
|
+
return resolveAddressNetworkFamily(left) === resolveAddressNetworkFamily(right);
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/**
|
|
1206
|
+
* Detect network from address prefix.
|
|
1207
|
+
* `nq1...` / `tnq1...` are AuthScript witness-v1 destinations.
|
|
1208
|
+
*
|
|
1166
1209
|
* @param {string} address - Neurai address
|
|
1167
1210
|
* @returns {string} Network name ('xna', 'xna-test', 'xna-pq', or 'xna-pq-test')
|
|
1168
1211
|
*/
|
|
1169
1212
|
function detectNetworkFromAddress(address) {
|
|
1170
|
-
if (address.startsWith(NETWORKS.MAINNET_PQ.
|
|
1213
|
+
if (address.startsWith(NETWORKS.MAINNET_PQ.authScriptAddressPrefix)) {
|
|
1171
1214
|
return 'xna-pq';
|
|
1172
|
-
} else if (address.startsWith(NETWORKS.TESTNET_PQ.
|
|
1215
|
+
} else if (address.startsWith(NETWORKS.TESTNET_PQ.authScriptAddressPrefix)) {
|
|
1173
1216
|
return 'xna-pq-test';
|
|
1174
1217
|
} else if (address.startsWith('N')) {
|
|
1175
1218
|
return 'xna';
|
|
@@ -1182,9 +1225,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1182
1225
|
|
|
1183
1226
|
networks = {
|
|
1184
1227
|
NETWORKS,
|
|
1228
|
+
MAINNET_NETWORKS,
|
|
1229
|
+
TESTNET_NETWORKS,
|
|
1185
1230
|
ASSET_NAME_RULES,
|
|
1186
1231
|
ASSET_LIMITS,
|
|
1187
1232
|
getNetworkConfig,
|
|
1233
|
+
resolveAddressNetworkFamily,
|
|
1234
|
+
areAddressNetworksCompatible,
|
|
1188
1235
|
detectNetworkFromAddress
|
|
1189
1236
|
};
|
|
1190
1237
|
return networks;
|
|
@@ -1212,9 +1259,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1212
1259
|
} = requireBurnAddresses();
|
|
1213
1260
|
const {
|
|
1214
1261
|
NETWORKS,
|
|
1262
|
+
MAINNET_NETWORKS,
|
|
1263
|
+
TESTNET_NETWORKS,
|
|
1215
1264
|
ASSET_NAME_RULES,
|
|
1216
1265
|
ASSET_LIMITS,
|
|
1217
1266
|
getNetworkConfig,
|
|
1267
|
+
resolveAddressNetworkFamily,
|
|
1268
|
+
areAddressNetworksCompatible,
|
|
1218
1269
|
detectNetworkFromAddress
|
|
1219
1270
|
} = requireNetworks();
|
|
1220
1271
|
|
|
@@ -1237,9 +1288,13 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1237
1288
|
|
|
1238
1289
|
// Networks
|
|
1239
1290
|
NETWORKS,
|
|
1291
|
+
MAINNET_NETWORKS,
|
|
1292
|
+
TESTNET_NETWORKS,
|
|
1240
1293
|
ASSET_NAME_RULES,
|
|
1241
1294
|
ASSET_LIMITS,
|
|
1242
1295
|
getNetworkConfig,
|
|
1296
|
+
resolveAddressNetworkFamily,
|
|
1297
|
+
areAddressNetworksCompatible,
|
|
1243
1298
|
detectNetworkFromAddress
|
|
1244
1299
|
};
|
|
1245
1300
|
return constants$1;
|
|
@@ -1856,7 +1911,11 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1856
1911
|
function requireNetworkDetector () {
|
|
1857
1912
|
if (hasRequiredNetworkDetector) return networkDetector;
|
|
1858
1913
|
hasRequiredNetworkDetector = 1;
|
|
1859
|
-
const {
|
|
1914
|
+
const {
|
|
1915
|
+
NETWORKS,
|
|
1916
|
+
areAddressNetworksCompatible,
|
|
1917
|
+
resolveAddressNetworkFamily
|
|
1918
|
+
} = requireConstants();
|
|
1860
1919
|
|
|
1861
1920
|
class NetworkDetector {
|
|
1862
1921
|
/**
|
|
@@ -1893,18 +1952,18 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1893
1952
|
/**
|
|
1894
1953
|
* Detect network from address
|
|
1895
1954
|
* @param {string} address - Neurai address
|
|
1896
|
-
* @returns {string} Network
|
|
1955
|
+
* @returns {string} Network label ('xna', 'xna-test', 'xna-pq', or 'xna-pq-test')
|
|
1897
1956
|
*/
|
|
1898
1957
|
static detectFromAddress(address) {
|
|
1899
1958
|
if (!address || typeof address !== 'string') {
|
|
1900
1959
|
throw new Error('Address must be a non-empty string');
|
|
1901
1960
|
}
|
|
1902
1961
|
|
|
1903
|
-
if (address.startsWith(NETWORKS.MAINNET_PQ.
|
|
1962
|
+
if (address.startsWith(NETWORKS.MAINNET_PQ.authScriptAddressPrefix)) {
|
|
1904
1963
|
return 'xna-pq';
|
|
1905
1964
|
}
|
|
1906
1965
|
|
|
1907
|
-
if (address.startsWith(NETWORKS.TESTNET_PQ.
|
|
1966
|
+
if (address.startsWith(NETWORKS.TESTNET_PQ.authScriptAddressPrefix)) {
|
|
1908
1967
|
return 'xna-pq-test';
|
|
1909
1968
|
}
|
|
1910
1969
|
|
|
@@ -1924,31 +1983,32 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1924
1983
|
/**
|
|
1925
1984
|
* Detect network from multiple addresses
|
|
1926
1985
|
* @param {string[]} addresses - Array of addresses
|
|
1927
|
-
* @returns {string} Network
|
|
1986
|
+
* @returns {string} Network label. Mixed legacy/AuthScript addresses on the same
|
|
1987
|
+
* chain are normalized to the chain family label (`xna` or `xna-test`).
|
|
1928
1988
|
*/
|
|
1929
1989
|
static detectFromAddresses(addresses) {
|
|
1930
1990
|
if (!Array.isArray(addresses) || addresses.length === 0) {
|
|
1931
1991
|
throw new Error('Addresses must be a non-empty array');
|
|
1932
1992
|
}
|
|
1933
1993
|
|
|
1934
|
-
|
|
1935
|
-
const
|
|
1994
|
+
const firstNetwork = this.detectFromAddress(addresses[0]);
|
|
1995
|
+
const family = resolveAddressNetworkFamily(firstNetwork);
|
|
1936
1996
|
|
|
1937
1997
|
// Verify all addresses are from the same network
|
|
1938
1998
|
for (let i = 1; i < addresses.length; i++) {
|
|
1939
1999
|
const otherNetwork = this.detectFromAddress(addresses[i]);
|
|
1940
|
-
if (otherNetwork
|
|
1941
|
-
throw new Error(`Mixed network addresses detected: ${
|
|
2000
|
+
if (!areAddressNetworksCompatible(firstNetwork, otherNetwork)) {
|
|
2001
|
+
throw new Error(`Mixed network addresses detected: ${firstNetwork} and ${otherNetwork}`);
|
|
1942
2002
|
}
|
|
1943
2003
|
}
|
|
1944
2004
|
|
|
1945
|
-
return
|
|
2005
|
+
return family === 'mainnet' ? 'xna' : 'xna-test';
|
|
1946
2006
|
}
|
|
1947
2007
|
|
|
1948
2008
|
/**
|
|
1949
2009
|
* Validate that addresses match expected network
|
|
1950
2010
|
* @param {string[]} addresses - Array of addresses
|
|
1951
|
-
* @param {string} expectedNetwork - Expected network
|
|
2011
|
+
* @param {string} expectedNetwork - Expected network label
|
|
1952
2012
|
* @returns {boolean} True if all addresses match network
|
|
1953
2013
|
*/
|
|
1954
2014
|
static validateAddressesNetwork(addresses, expectedNetwork) {
|
|
@@ -1958,7 +2018,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
1958
2018
|
|
|
1959
2019
|
for (const address of addresses) {
|
|
1960
2020
|
const network = this.detectFromAddress(address);
|
|
1961
|
-
if (network
|
|
2021
|
+
if (!areAddressNetworksCompatible(network, expectedNetwork)) {
|
|
1962
2022
|
throw new Error(
|
|
1963
2023
|
`Address ${address} is from ${network} but expected ${expectedNetwork}`
|
|
1964
2024
|
);
|
|
@@ -3310,52 +3370,164 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3310
3370
|
const { ASSET_NAME_RULES } = requireConstants();
|
|
3311
3371
|
const { InvalidAssetNameError } = requireErrors();
|
|
3312
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
|
+
|
|
3313
3499
|
class AssetNameValidator {
|
|
3314
3500
|
/**
|
|
3315
3501
|
* Validate ROOT asset name
|
|
3316
|
-
* Rules: 3-
|
|
3317
|
-
* 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
|
|
3318
3504
|
* Cannot be reserved names
|
|
3319
3505
|
*/
|
|
3320
|
-
static validateRoot(name) {
|
|
3321
|
-
|
|
3322
|
-
throw new InvalidAssetNameError('Asset name must be a non-empty string', name);
|
|
3323
|
-
}
|
|
3506
|
+
static validateRoot(name, network = 'xna') {
|
|
3507
|
+
ensureName(name, 'Asset name');
|
|
3324
3508
|
|
|
3325
|
-
|
|
3326
|
-
|
|
3509
|
+
const maxLength = getRootOrSubMaxLength(network);
|
|
3510
|
+
|
|
3511
|
+
if (name.length < MIN_ASSET_LENGTH || name.length > maxLength) {
|
|
3327
3512
|
throw new InvalidAssetNameError(
|
|
3328
|
-
`ROOT asset name must be ${
|
|
3513
|
+
`ROOT asset name must be ${MIN_ASSET_LENGTH}-${maxLength} characters`,
|
|
3329
3514
|
name
|
|
3330
3515
|
);
|
|
3331
3516
|
}
|
|
3332
3517
|
|
|
3333
|
-
|
|
3334
|
-
if (name !== name.toUpperCase()) {
|
|
3335
|
-
throw new InvalidAssetNameError('Asset name must be uppercase', name);
|
|
3336
|
-
}
|
|
3518
|
+
ensureUppercase(name, 'Asset name must be uppercase');
|
|
3337
3519
|
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
throw new InvalidAssetNameError(
|
|
3341
|
-
`Asset name cannot start with: ${ASSET_NAME_RULES.ROOT.cannotStartWith.join(', ')}`,
|
|
3342
|
-
name
|
|
3343
|
-
);
|
|
3520
|
+
if (NEURAI_NAMES.test(name)) {
|
|
3521
|
+
throw new InvalidAssetNameError(`${name} is a reserved asset name`, name);
|
|
3344
3522
|
}
|
|
3345
3523
|
|
|
3346
|
-
|
|
3347
|
-
if (!ASSET_NAME_RULES.ROOT.pattern.test(name)) {
|
|
3524
|
+
if (!isRootNameValid(name)) {
|
|
3348
3525
|
throw new InvalidAssetNameError(
|
|
3349
|
-
'
|
|
3526
|
+
'Name contains invalid characters (Valid characters are: A-Z 0-9 _ .) (special characters can\'t be the first or last characters)',
|
|
3350
3527
|
name
|
|
3351
3528
|
);
|
|
3352
3529
|
}
|
|
3353
3530
|
|
|
3354
|
-
// Reserved names check
|
|
3355
|
-
if (ASSET_NAME_RULES.ROOT.reserved.includes(name)) {
|
|
3356
|
-
throw new InvalidAssetNameError(`${name} is a reserved asset name`, name);
|
|
3357
|
-
}
|
|
3358
|
-
|
|
3359
3531
|
return true;
|
|
3360
3532
|
}
|
|
3361
3533
|
|
|
@@ -3363,39 +3535,25 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3363
3535
|
* Validate SUB asset name
|
|
3364
3536
|
* Format: ROOT/SUBNAME
|
|
3365
3537
|
*/
|
|
3366
|
-
static validateSub(name) {
|
|
3367
|
-
|
|
3368
|
-
throw new InvalidAssetNameError('SUB asset name must be a non-empty string', name);
|
|
3369
|
-
}
|
|
3538
|
+
static validateSub(name, network = 'xna') {
|
|
3539
|
+
ensureName(name, 'SUB asset name');
|
|
3370
3540
|
|
|
3371
|
-
|
|
3372
|
-
if (parts.length !== 2) {
|
|
3541
|
+
if (!name.includes(ASSET_NAME_RULES.SUB.separator)) {
|
|
3373
3542
|
throw new InvalidAssetNameError(
|
|
3374
3543
|
`SUB asset must be in ${ASSET_NAME_RULES.SUB.separator} format (ROOT/SUBNAME)`,
|
|
3375
3544
|
name
|
|
3376
3545
|
);
|
|
3377
3546
|
}
|
|
3378
3547
|
|
|
3379
|
-
|
|
3380
|
-
|
|
3381
|
-
// Validate root part
|
|
3382
|
-
this.validateRoot(rootName);
|
|
3548
|
+
ensureMaxLength(name, getRootOrSubMaxLength(network), 'SUB asset name');
|
|
3383
3549
|
|
|
3384
|
-
|
|
3385
|
-
if (subName.length < ASSET_NAME_RULES.SUB.minLength || subName.length > ASSET_NAME_RULES.SUB.maxLength) {
|
|
3386
|
-
throw new InvalidAssetNameError(
|
|
3387
|
-
`SUB asset name must be ${ASSET_NAME_RULES.SUB.minLength}-${ASSET_NAME_RULES.SUB.maxLength} characters`,
|
|
3388
|
-
name
|
|
3389
|
-
);
|
|
3390
|
-
}
|
|
3391
|
-
|
|
3392
|
-
if (subName !== subName.toUpperCase()) {
|
|
3550
|
+
if (name !== name.toUpperCase()) {
|
|
3393
3551
|
throw new InvalidAssetNameError('SUB asset name must be uppercase', name);
|
|
3394
3552
|
}
|
|
3395
3553
|
|
|
3396
|
-
if (!
|
|
3554
|
+
if (!isNameValidBeforeTag(name)) {
|
|
3397
3555
|
throw new InvalidAssetNameError(
|
|
3398
|
-
'
|
|
3556
|
+
'Name contains invalid characters (Valid characters are: A-Z 0-9 _ .) (special characters can\'t be the first or last characters)',
|
|
3399
3557
|
name
|
|
3400
3558
|
);
|
|
3401
3559
|
}
|
|
@@ -3407,10 +3565,10 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3407
3565
|
* Validate UNIQUE asset name
|
|
3408
3566
|
* Format: ROOT#TAG
|
|
3409
3567
|
*/
|
|
3410
|
-
static validateUnique(name) {
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3568
|
+
static validateUnique(name, network = 'xna') {
|
|
3569
|
+
ensureName(name, 'UNIQUE asset name');
|
|
3570
|
+
|
|
3571
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'UNIQUE asset name');
|
|
3414
3572
|
|
|
3415
3573
|
const parts = name.split(ASSET_NAME_RULES.UNIQUE.separator);
|
|
3416
3574
|
if (parts.length !== 2) {
|
|
@@ -3422,24 +3580,9 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3422
3580
|
|
|
3423
3581
|
const [rootName, tag] = parts;
|
|
3424
3582
|
|
|
3425
|
-
|
|
3426
|
-
this.validateRoot(rootName);
|
|
3427
|
-
|
|
3428
|
-
// Validate tag
|
|
3429
|
-
if (tag.length < ASSET_NAME_RULES.UNIQUE.minLength || tag.length > ASSET_NAME_RULES.UNIQUE.maxLength) {
|
|
3430
|
-
throw new InvalidAssetNameError(
|
|
3431
|
-
`UNIQUE tag must be ${ASSET_NAME_RULES.UNIQUE.minLength}-${ASSET_NAME_RULES.UNIQUE.maxLength} characters`,
|
|
3432
|
-
name
|
|
3433
|
-
);
|
|
3434
|
-
}
|
|
3435
|
-
|
|
3436
|
-
if (tag !== tag.toUpperCase()) {
|
|
3437
|
-
throw new InvalidAssetNameError('UNIQUE tag must be uppercase', name);
|
|
3438
|
-
}
|
|
3439
|
-
|
|
3440
|
-
if (!ASSET_NAME_RULES.UNIQUE.pattern.test(tag)) {
|
|
3583
|
+
if (!isNameValidBeforeTag(rootName) || !UNIQUE_TAG_CHARACTERS.test(tag)) {
|
|
3441
3584
|
throw new InvalidAssetNameError(
|
|
3442
|
-
'
|
|
3585
|
+
'Unique name contains invalid characters (Valid characters are: A-Z a-z 0-9 @ $ % & * ( ) [ ] { } _ . ? : -)',
|
|
3443
3586
|
name
|
|
3444
3587
|
);
|
|
3445
3588
|
}
|
|
@@ -3451,10 +3594,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3451
3594
|
* Validate QUALIFIER asset name
|
|
3452
3595
|
* Format: #NAME or #ROOT/SUB
|
|
3453
3596
|
*/
|
|
3454
|
-
static validateQualifier(name) {
|
|
3455
|
-
|
|
3456
|
-
throw new InvalidAssetNameError('QUALIFIER asset name must be a non-empty string', name);
|
|
3457
|
-
}
|
|
3597
|
+
static validateQualifier(name, network = 'xna') {
|
|
3598
|
+
ensureName(name, 'QUALIFIER asset name');
|
|
3458
3599
|
|
|
3459
3600
|
if (!name.startsWith(ASSET_NAME_RULES.QUALIFIER.prefix)) {
|
|
3460
3601
|
throw new InvalidAssetNameError(
|
|
@@ -3463,58 +3604,17 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3463
3604
|
);
|
|
3464
3605
|
}
|
|
3465
3606
|
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
if (withoutPrefix.includes(ASSET_NAME_RULES.QUALIFIER.separator)) {
|
|
3469
|
-
// Sub-qualifier: #ROOT/SUB
|
|
3470
|
-
const parts = withoutPrefix.split(ASSET_NAME_RULES.QUALIFIER.separator);
|
|
3471
|
-
if (parts.length !== 2) {
|
|
3472
|
-
throw new InvalidAssetNameError(
|
|
3473
|
-
'SUB_QUALIFIER must be in #ROOT/SUB format',
|
|
3474
|
-
name
|
|
3475
|
-
);
|
|
3476
|
-
}
|
|
3477
|
-
|
|
3478
|
-
// Validate each part as a qualifier name (without the #)
|
|
3479
|
-
parts.forEach(part => {
|
|
3480
|
-
if (part.length < ASSET_NAME_RULES.QUALIFIER.minLength || part.length > ASSET_NAME_RULES.QUALIFIER.maxLength) {
|
|
3481
|
-
throw new InvalidAssetNameError(
|
|
3482
|
-
`QUALIFIER name must be ${ASSET_NAME_RULES.QUALIFIER.minLength}-${ASSET_NAME_RULES.QUALIFIER.maxLength} characters`,
|
|
3483
|
-
name
|
|
3484
|
-
);
|
|
3485
|
-
}
|
|
3486
|
-
|
|
3487
|
-
if (part !== part.toUpperCase()) {
|
|
3488
|
-
throw new InvalidAssetNameError('QUALIFIER name must be uppercase', name);
|
|
3489
|
-
}
|
|
3490
|
-
|
|
3491
|
-
if (!ASSET_NAME_RULES.QUALIFIER.pattern.test(part)) {
|
|
3492
|
-
throw new InvalidAssetNameError(
|
|
3493
|
-
'QUALIFIER name can only contain A-Z, 0-9, and underscore',
|
|
3494
|
-
name
|
|
3495
|
-
);
|
|
3496
|
-
}
|
|
3497
|
-
});
|
|
3498
|
-
} else {
|
|
3499
|
-
// Root qualifier: #NAME
|
|
3500
|
-
if (withoutPrefix.length < ASSET_NAME_RULES.QUALIFIER.minLength ||
|
|
3501
|
-
withoutPrefix.length > ASSET_NAME_RULES.QUALIFIER.maxLength) {
|
|
3502
|
-
throw new InvalidAssetNameError(
|
|
3503
|
-
`QUALIFIER name must be ${ASSET_NAME_RULES.QUALIFIER.minLength}-${ASSET_NAME_RULES.QUALIFIER.maxLength} characters`,
|
|
3504
|
-
name
|
|
3505
|
-
);
|
|
3506
|
-
}
|
|
3607
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'QUALIFIER asset name');
|
|
3507
3608
|
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3609
|
+
if (name !== name.toUpperCase()) {
|
|
3610
|
+
throw new InvalidAssetNameError('QUALIFIER name must be uppercase', name);
|
|
3611
|
+
}
|
|
3511
3612
|
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
}
|
|
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
|
+
);
|
|
3518
3618
|
}
|
|
3519
3619
|
|
|
3520
3620
|
return true;
|
|
@@ -3524,10 +3624,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3524
3624
|
* Validate RESTRICTED asset name
|
|
3525
3625
|
* Format: $NAME
|
|
3526
3626
|
*/
|
|
3527
|
-
static validateRestricted(name) {
|
|
3528
|
-
|
|
3529
|
-
throw new InvalidAssetNameError('RESTRICTED asset name must be a non-empty string', name);
|
|
3530
|
-
}
|
|
3627
|
+
static validateRestricted(name, network = 'xna') {
|
|
3628
|
+
ensureName(name, 'RESTRICTED asset name');
|
|
3531
3629
|
|
|
3532
3630
|
if (!name.startsWith(ASSET_NAME_RULES.RESTRICTED.prefix)) {
|
|
3533
3631
|
throw new InvalidAssetNameError(
|
|
@@ -3536,10 +3634,18 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3536
3634
|
);
|
|
3537
3635
|
}
|
|
3538
3636
|
|
|
3539
|
-
|
|
3637
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'RESTRICTED asset name');
|
|
3540
3638
|
|
|
3541
|
-
|
|
3542
|
-
|
|
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
|
+
}
|
|
3543
3649
|
|
|
3544
3650
|
return true;
|
|
3545
3651
|
}
|
|
@@ -3548,10 +3654,8 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3548
3654
|
* Validate DEPIN asset name
|
|
3549
3655
|
* Format: &NAME or &NAME/SUB[/...]
|
|
3550
3656
|
*/
|
|
3551
|
-
static validateDepin(name) {
|
|
3552
|
-
|
|
3553
|
-
throw new InvalidAssetNameError('DEPIN asset name must be a non-empty string', name);
|
|
3554
|
-
}
|
|
3657
|
+
static validateDepin(name, network) {
|
|
3658
|
+
ensureName(name, 'DEPIN asset name');
|
|
3555
3659
|
|
|
3556
3660
|
if (!name.startsWith(ASSET_NAME_RULES.DEPIN.prefix)) {
|
|
3557
3661
|
throw new InvalidAssetNameError(
|
|
@@ -3560,58 +3664,41 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3560
3664
|
);
|
|
3561
3665
|
}
|
|
3562
3666
|
|
|
3563
|
-
if (
|
|
3564
|
-
throw new InvalidAssetNameError(
|
|
3565
|
-
`DEPIN asset name cannot exceed ${ASSET_NAME_RULES.DEPIN.maxLength} characters`,
|
|
3566
|
-
name
|
|
3567
|
-
);
|
|
3667
|
+
if (network && !isTestnet(network)) {
|
|
3668
|
+
throw new InvalidAssetNameError('DEPIN assets are only available in testnet', name);
|
|
3568
3669
|
}
|
|
3569
3670
|
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
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);
|
|
3573
3675
|
}
|
|
3574
3676
|
|
|
3575
|
-
|
|
3576
|
-
if (rootPart.length < ASSET_NAME_RULES.DEPIN.minLength) {
|
|
3677
|
+
if (!isDepinIndicator(name)) {
|
|
3577
3678
|
throw new InvalidAssetNameError(
|
|
3578
|
-
|
|
3679
|
+
'DEPIN asset name can only contain A-Z, 0-9, underscore, period, and separator /',
|
|
3579
3680
|
name
|
|
3580
3681
|
);
|
|
3581
3682
|
}
|
|
3582
3683
|
|
|
3583
|
-
|
|
3584
|
-
throw new InvalidAssetNameError('DEPIN asset name must be uppercase', name);
|
|
3585
|
-
}
|
|
3684
|
+
const parts = name.split(ASSET_NAME_RULES.DEPIN.separator);
|
|
3586
3685
|
|
|
3587
|
-
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) {
|
|
3588
3696
|
throw new InvalidAssetNameError(
|
|
3589
|
-
|
|
3697
|
+
`DEPIN name must be at least ${MIN_ASSET_LENGTH} characters (excluding &)`,
|
|
3590
3698
|
name
|
|
3591
3699
|
);
|
|
3592
3700
|
}
|
|
3593
3701
|
|
|
3594
|
-
const subParts = parts.slice(1);
|
|
3595
|
-
subParts.forEach(part => {
|
|
3596
|
-
if (part.length < ASSET_NAME_RULES.DEPIN.minLength) {
|
|
3597
|
-
throw new InvalidAssetNameError(
|
|
3598
|
-
`Each DEPIN sub-part must be at least ${ASSET_NAME_RULES.DEPIN.minLength} characters`,
|
|
3599
|
-
name
|
|
3600
|
-
);
|
|
3601
|
-
}
|
|
3602
|
-
|
|
3603
|
-
if (part !== part.toUpperCase()) {
|
|
3604
|
-
throw new InvalidAssetNameError('DEPIN asset name must be uppercase', name);
|
|
3605
|
-
}
|
|
3606
|
-
|
|
3607
|
-
if (!ASSET_NAME_RULES.DEPIN.pattern.test(part)) {
|
|
3608
|
-
throw new InvalidAssetNameError(
|
|
3609
|
-
'DEPIN asset name can only contain A-Z, 0-9, underscore, and period',
|
|
3610
|
-
name
|
|
3611
|
-
);
|
|
3612
|
-
}
|
|
3613
|
-
});
|
|
3614
|
-
|
|
3615
3702
|
return true;
|
|
3616
3703
|
}
|
|
3617
3704
|
|
|
@@ -3619,24 +3706,31 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3619
3706
|
* Validate owner token name
|
|
3620
3707
|
* Format: ASSETNAME!
|
|
3621
3708
|
*/
|
|
3622
|
-
static validateOwnerToken(name) {
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3709
|
+
static validateOwnerToken(name, network) {
|
|
3710
|
+
ensureName(name, 'Owner token name');
|
|
3711
|
+
|
|
3712
|
+
ensureMaxLength(name, getMaxAssetNameLength(network), 'Owner token name');
|
|
3626
3713
|
|
|
3627
3714
|
if (!name.endsWith('!')) {
|
|
3628
3715
|
throw new InvalidAssetNameError('Owner token must end with !', name);
|
|
3629
3716
|
}
|
|
3630
3717
|
|
|
3631
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
|
+
})());
|
|
3632
3728
|
|
|
3633
|
-
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
} else {
|
|
3639
|
-
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
|
+
);
|
|
3640
3734
|
}
|
|
3641
3735
|
|
|
3642
3736
|
return true;
|
|
@@ -3647,27 +3741,27 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
3647
3741
|
* @param {string} name - Asset name
|
|
3648
3742
|
* @returns {string} Asset type ('ROOT', 'SUB', 'UNIQUE', 'QUALIFIER', 'RESTRICTED', 'DEPIN', 'OWNER')
|
|
3649
3743
|
*/
|
|
3650
|
-
static validateAndDetectType(name) {
|
|
3744
|
+
static validateAndDetectType(name, network) {
|
|
3651
3745
|
if (name.endsWith('!')) {
|
|
3652
|
-
this.validateOwnerToken(name);
|
|
3746
|
+
this.validateOwnerToken(name, network);
|
|
3653
3747
|
return 'OWNER';
|
|
3654
3748
|
} else if (name.startsWith('#')) {
|
|
3655
|
-
this.validateQualifier(name);
|
|
3749
|
+
this.validateQualifier(name, network);
|
|
3656
3750
|
return name.includes('/') ? 'SUB_QUALIFIER' : 'QUALIFIER';
|
|
3657
3751
|
} else if (name.startsWith('$')) {
|
|
3658
|
-
this.validateRestricted(name);
|
|
3752
|
+
this.validateRestricted(name, network);
|
|
3659
3753
|
return 'RESTRICTED';
|
|
3660
3754
|
} else if (name.startsWith('&')) {
|
|
3661
|
-
this.validateDepin(name);
|
|
3755
|
+
this.validateDepin(name, network);
|
|
3662
3756
|
return 'DEPIN';
|
|
3663
3757
|
} else if (name.includes('#')) {
|
|
3664
|
-
this.validateUnique(name);
|
|
3758
|
+
this.validateUnique(name, network);
|
|
3665
3759
|
return 'UNIQUE';
|
|
3666
3760
|
} else if (name.includes('/')) {
|
|
3667
|
-
this.validateSub(name);
|
|
3761
|
+
this.validateSub(name, network);
|
|
3668
3762
|
return 'SUB';
|
|
3669
3763
|
} else {
|
|
3670
|
-
this.validateRoot(name);
|
|
3764
|
+
this.validateRoot(name, network);
|
|
3671
3765
|
return 'ROOT';
|
|
3672
3766
|
}
|
|
3673
3767
|
}
|
|
@@ -4344,22 +4438,22 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
4344
4438
|
|
|
4345
4439
|
switch (type) {
|
|
4346
4440
|
case 'ROOT':
|
|
4347
|
-
AssetNameValidator.validateRoot(assetName);
|
|
4441
|
+
AssetNameValidator.validateRoot(assetName, this.network);
|
|
4348
4442
|
break;
|
|
4349
4443
|
case 'SUB':
|
|
4350
|
-
AssetNameValidator.validateSub(assetName);
|
|
4444
|
+
AssetNameValidator.validateSub(assetName, this.network);
|
|
4351
4445
|
break;
|
|
4352
4446
|
case 'UNIQUE':
|
|
4353
|
-
AssetNameValidator.validateUnique(assetName);
|
|
4447
|
+
AssetNameValidator.validateUnique(assetName, this.network);
|
|
4354
4448
|
break;
|
|
4355
4449
|
case 'QUALIFIER':
|
|
4356
|
-
AssetNameValidator.validateQualifier(assetName);
|
|
4450
|
+
AssetNameValidator.validateQualifier(assetName, this.network);
|
|
4357
4451
|
break;
|
|
4358
4452
|
case 'RESTRICTED':
|
|
4359
|
-
AssetNameValidator.validateRestricted(assetName);
|
|
4453
|
+
AssetNameValidator.validateRestricted(assetName, this.network);
|
|
4360
4454
|
break;
|
|
4361
4455
|
case 'DEPIN':
|
|
4362
|
-
AssetNameValidator.validateDepin(assetName);
|
|
4456
|
+
AssetNameValidator.validateDepin(assetName, this.network);
|
|
4363
4457
|
break;
|
|
4364
4458
|
default:
|
|
4365
4459
|
throw new Error(`Unknown asset type: ${type}`);
|
|
@@ -5780,7 +5874,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
5780
5874
|
*
|
|
5781
5875
|
* QUALIFIER assets:
|
|
5782
5876
|
* - KYC/compliance tags (e.g., #KYC_VERIFIED, #ACCREDITED)
|
|
5783
|
-
* - Format: #NAME or #ROOT
|
|
5877
|
+
* - Format: #NAME or #ROOT/#SUB
|
|
5784
5878
|
* - Cost: 2000 XNA (root) or 200 XNA (sub-qualifier)
|
|
5785
5879
|
* - Quantity: 1-10 units only
|
|
5786
5880
|
* - Units: Always 0 (non-divisible)
|
|
@@ -7245,7 +7339,7 @@ var NeuraiAssetsBundle = (function (exports) {
|
|
|
7245
7339
|
/**
|
|
7246
7340
|
* Create a ROOT asset
|
|
7247
7341
|
* @param {object} params - Asset creation parameters
|
|
7248
|
-
|
|
7342
|
+
* @param {string} params.assetName - Asset name (3-31 visible chars on mainnet, A-Z 0-9 _ .)
|
|
7249
7343
|
* @param {number} params.quantity - Total supply
|
|
7250
7344
|
* @param {number} [params.units=0] - Decimal places (0-8)
|
|
7251
7345
|
* @param {boolean} [params.reissuable=true] - Can mint more later
|