@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,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset Name Parser
|
|
3
|
+
* Parses and analyzes asset names
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { AssetType } = require('../constants');
|
|
7
|
+
|
|
8
|
+
class AssetNameParser {
|
|
9
|
+
/**
|
|
10
|
+
* Parse asset name and extract information
|
|
11
|
+
* @param {string} name - Asset name
|
|
12
|
+
* @returns {object} Parsed information
|
|
13
|
+
*/
|
|
14
|
+
static parse(name) {
|
|
15
|
+
const isOwner = name.endsWith('!');
|
|
16
|
+
const isRestricted = name.startsWith('$');
|
|
17
|
+
const isQualifier = name.startsWith('#');
|
|
18
|
+
const cleanName = isOwner ? name.slice(0, -1) : name;
|
|
19
|
+
|
|
20
|
+
let type;
|
|
21
|
+
let parent = null;
|
|
22
|
+
let subName = null;
|
|
23
|
+
let tag = null;
|
|
24
|
+
let prefix = null;
|
|
25
|
+
|
|
26
|
+
if (isQualifier) {
|
|
27
|
+
// QUALIFIER or SUB_QUALIFIER: #NAME or #ROOT/SUB
|
|
28
|
+
if (cleanName.includes('/')) {
|
|
29
|
+
type = AssetType.SUB_QUALIFIER;
|
|
30
|
+
const withoutHash = cleanName.substring(1);
|
|
31
|
+
const parts = withoutHash.split('/');
|
|
32
|
+
parent = '#' + parts[0];
|
|
33
|
+
subName = parts[1];
|
|
34
|
+
prefix = '#';
|
|
35
|
+
} else {
|
|
36
|
+
type = AssetType.QUALIFIER;
|
|
37
|
+
prefix = '#';
|
|
38
|
+
}
|
|
39
|
+
} else if (isRestricted) {
|
|
40
|
+
// RESTRICTED: $NAME
|
|
41
|
+
type = AssetType.RESTRICTED;
|
|
42
|
+
prefix = '$';
|
|
43
|
+
} else if (cleanName.includes('#')) {
|
|
44
|
+
// UNIQUE: ROOT#TAG
|
|
45
|
+
type = AssetType.UNIQUE;
|
|
46
|
+
const parts = cleanName.split('#');
|
|
47
|
+
parent = parts[0];
|
|
48
|
+
tag = parts[1];
|
|
49
|
+
} else if (cleanName.includes('/')) {
|
|
50
|
+
// SUB: ROOT/SUB
|
|
51
|
+
type = AssetType.SUB;
|
|
52
|
+
const parts = cleanName.split('/');
|
|
53
|
+
parent = parts[0];
|
|
54
|
+
subName = parts[1];
|
|
55
|
+
} else {
|
|
56
|
+
// ROOT
|
|
57
|
+
type = AssetType.ROOT;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Override type if owner token
|
|
61
|
+
if (isOwner) {
|
|
62
|
+
const baseType = type;
|
|
63
|
+
type = AssetType.OWNER;
|
|
64
|
+
return {
|
|
65
|
+
type,
|
|
66
|
+
baseType,
|
|
67
|
+
parent,
|
|
68
|
+
name: cleanName,
|
|
69
|
+
subName,
|
|
70
|
+
tag,
|
|
71
|
+
prefix,
|
|
72
|
+
isOwner: true,
|
|
73
|
+
isRestricted: cleanName.startsWith('$'),
|
|
74
|
+
isQualifier: false,
|
|
75
|
+
fullName: name,
|
|
76
|
+
baseName: cleanName
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
type,
|
|
82
|
+
parent,
|
|
83
|
+
name: cleanName,
|
|
84
|
+
subName,
|
|
85
|
+
tag,
|
|
86
|
+
prefix,
|
|
87
|
+
isOwner,
|
|
88
|
+
isRestricted,
|
|
89
|
+
isQualifier,
|
|
90
|
+
fullName: name,
|
|
91
|
+
baseName: cleanName
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Get asset type from name
|
|
97
|
+
* @param {string} name - Asset name
|
|
98
|
+
* @returns {number} AssetType enum value
|
|
99
|
+
*/
|
|
100
|
+
static getType(name) {
|
|
101
|
+
return this.parse(name).type;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Get parent asset name
|
|
106
|
+
* @param {string} name - Asset name
|
|
107
|
+
* @returns {string|null} Parent asset name or null
|
|
108
|
+
*/
|
|
109
|
+
static getParent(name) {
|
|
110
|
+
return this.parse(name).parent;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Check if asset is an owner token
|
|
115
|
+
* @param {string} name - Asset name
|
|
116
|
+
* @returns {boolean} True if owner token
|
|
117
|
+
*/
|
|
118
|
+
static isOwnerToken(name) {
|
|
119
|
+
return name.endsWith('!');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get owner token name for an asset
|
|
124
|
+
* @param {string} assetName - Asset name
|
|
125
|
+
* @returns {string} Owner token name (assetName + '!')
|
|
126
|
+
*/
|
|
127
|
+
static getOwnerTokenName(assetName) {
|
|
128
|
+
if (this.isOwnerToken(assetName)) {
|
|
129
|
+
return assetName;
|
|
130
|
+
}
|
|
131
|
+
return assetName + '!';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Get base asset name from owner token
|
|
136
|
+
* @param {string} ownerTokenName - Owner token name (with !)
|
|
137
|
+
* @returns {string} Base asset name (without !)
|
|
138
|
+
*/
|
|
139
|
+
static getBaseAssetName(ownerTokenName) {
|
|
140
|
+
if (this.isOwnerToken(ownerTokenName)) {
|
|
141
|
+
return ownerTokenName.slice(0, -1);
|
|
142
|
+
}
|
|
143
|
+
return ownerTokenName;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Check if asset is restricted
|
|
148
|
+
* @param {string} name - Asset name
|
|
149
|
+
* @returns {boolean} True if restricted
|
|
150
|
+
*/
|
|
151
|
+
static isRestricted(name) {
|
|
152
|
+
return name.startsWith('$');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Check if asset is a qualifier
|
|
157
|
+
* @param {string} name - Asset name
|
|
158
|
+
* @returns {boolean} True if qualifier
|
|
159
|
+
*/
|
|
160
|
+
static isQualifier(name) {
|
|
161
|
+
return name.startsWith('#');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Check if asset is unique (NFT)
|
|
166
|
+
* @param {string} name - Asset name
|
|
167
|
+
* @returns {boolean} True if unique
|
|
168
|
+
*/
|
|
169
|
+
static isUnique(name) {
|
|
170
|
+
return name.includes('#') && !name.startsWith('#');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Check if asset is a sub-asset
|
|
175
|
+
* @param {string} name - Asset name
|
|
176
|
+
* @returns {boolean} True if sub-asset
|
|
177
|
+
*/
|
|
178
|
+
static isSub(name) {
|
|
179
|
+
return name.includes('/') && !name.startsWith('#');
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Build unique asset name
|
|
184
|
+
* @param {string} rootName - Root asset name
|
|
185
|
+
* @param {string} tag - Unique tag
|
|
186
|
+
* @returns {string} Full unique asset name
|
|
187
|
+
*/
|
|
188
|
+
static buildUniqueName(rootName, tag) {
|
|
189
|
+
return `${rootName}#${tag}`;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Build sub-asset name
|
|
194
|
+
* @param {string} rootName - Root asset name
|
|
195
|
+
* @param {string} subName - Sub-asset name
|
|
196
|
+
* @returns {string} Full sub-asset name
|
|
197
|
+
*/
|
|
198
|
+
static buildSubName(rootName, subName) {
|
|
199
|
+
return `${rootName}/${subName}`;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = AssetNameParser;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utils Module
|
|
3
|
+
* Exports all utility classes
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const AssetNameParser = require('./assetNameParser');
|
|
7
|
+
const AmountConverter = require('./amountConverter');
|
|
8
|
+
const NetworkDetector = require('./networkDetector');
|
|
9
|
+
const OutputFormatter = require('./outputFormatter');
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
AssetNameParser,
|
|
13
|
+
AmountConverter,
|
|
14
|
+
NetworkDetector,
|
|
15
|
+
OutputFormatter
|
|
16
|
+
};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Detector
|
|
3
|
+
* Detects network type from various sources
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { NETWORKS } = require('../constants');
|
|
7
|
+
|
|
8
|
+
class NetworkDetector {
|
|
9
|
+
/**
|
|
10
|
+
* Detect network from RPC client
|
|
11
|
+
* Calls getblockchaininfo to determine network
|
|
12
|
+
* @param {Function} rpc - RPC function
|
|
13
|
+
* @returns {Promise<string>} Network name ('xna' or 'xna-test')
|
|
14
|
+
*/
|
|
15
|
+
static async detectFromRPC(rpc) {
|
|
16
|
+
try {
|
|
17
|
+
const blockchainInfo = await rpc('getblockchaininfo', []);
|
|
18
|
+
|
|
19
|
+
// Check chain name
|
|
20
|
+
if (blockchainInfo.chain === 'main') {
|
|
21
|
+
return 'xna';
|
|
22
|
+
} else if (blockchainInfo.chain === 'test') {
|
|
23
|
+
return 'xna-test';
|
|
24
|
+
} else if (blockchainInfo.chain === 'regtest') {
|
|
25
|
+
return 'xna-test'; // Treat regtest as testnet
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Fallback: check if testnet field exists
|
|
29
|
+
if (blockchainInfo.testnet === true) {
|
|
30
|
+
return 'xna-test';
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Default to mainnet
|
|
34
|
+
return 'xna';
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw new Error(`Failed to detect network from RPC: ${error.message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Detect network from address
|
|
42
|
+
* @param {string} address - Neurai address
|
|
43
|
+
* @returns {string} Network name ('xna' or 'xna-test')
|
|
44
|
+
*/
|
|
45
|
+
static detectFromAddress(address) {
|
|
46
|
+
if (!address || typeof address !== 'string') {
|
|
47
|
+
throw new Error('Address must be a non-empty string');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Mainnet addresses start with 'N'
|
|
51
|
+
if (address.startsWith(NETWORKS.MAINNET.addressPrefix)) {
|
|
52
|
+
return 'xna';
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Testnet addresses start with 'm' or 'n'
|
|
56
|
+
if (address.startsWith(NETWORKS.TESTNET.addressPrefix) || address.startsWith('n')) {
|
|
57
|
+
return 'xna-test';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
throw new Error(`Cannot detect network from address: ${address}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Detect network from multiple addresses
|
|
65
|
+
* @param {string[]} addresses - Array of addresses
|
|
66
|
+
* @returns {string} Network name ('xna' or 'xna-test')
|
|
67
|
+
*/
|
|
68
|
+
static detectFromAddresses(addresses) {
|
|
69
|
+
if (!Array.isArray(addresses) || addresses.length === 0) {
|
|
70
|
+
throw new Error('Addresses must be a non-empty array');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Detect from first address
|
|
74
|
+
const network = this.detectFromAddress(addresses[0]);
|
|
75
|
+
|
|
76
|
+
// Verify all addresses are from the same network
|
|
77
|
+
for (let i = 1; i < addresses.length; i++) {
|
|
78
|
+
const otherNetwork = this.detectFromAddress(addresses[i]);
|
|
79
|
+
if (otherNetwork !== network) {
|
|
80
|
+
throw new Error(`Mixed network addresses detected: ${network} and ${otherNetwork}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return network;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Validate that addresses match expected network
|
|
89
|
+
* @param {string[]} addresses - Array of addresses
|
|
90
|
+
* @param {string} expectedNetwork - Expected network ('xna' or 'xna-test')
|
|
91
|
+
* @returns {boolean} True if all addresses match network
|
|
92
|
+
*/
|
|
93
|
+
static validateAddressesNetwork(addresses, expectedNetwork) {
|
|
94
|
+
if (!Array.isArray(addresses) || addresses.length === 0) {
|
|
95
|
+
throw new Error('Addresses must be a non-empty array');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const address of addresses) {
|
|
99
|
+
const network = this.detectFromAddress(address);
|
|
100
|
+
if (network !== expectedNetwork) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Address ${address} is from ${network} but expected ${expectedNetwork}`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get network config from network name
|
|
112
|
+
* @param {string} network - Network name
|
|
113
|
+
* @returns {object} Network configuration
|
|
114
|
+
*/
|
|
115
|
+
static getNetworkConfig(network) {
|
|
116
|
+
if (network === 'xna' || network === 'mainnet') {
|
|
117
|
+
return NETWORKS.MAINNET;
|
|
118
|
+
} else if (network === 'xna-test' || network === 'testnet') {
|
|
119
|
+
return NETWORKS.TESTNET;
|
|
120
|
+
} else {
|
|
121
|
+
throw new Error(`Unknown network: ${network}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Check if network is mainnet
|
|
127
|
+
* @param {string} network - Network name
|
|
128
|
+
* @returns {boolean} True if mainnet
|
|
129
|
+
*/
|
|
130
|
+
static isMainnet(network) {
|
|
131
|
+
return network === 'xna' || network === 'mainnet';
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Check if network is testnet
|
|
136
|
+
* @param {string} network - Network name
|
|
137
|
+
* @returns {boolean} True if testnet
|
|
138
|
+
*/
|
|
139
|
+
static isTestnet(network) {
|
|
140
|
+
return network === 'xna-test' || network === 'testnet' || network === 'regtest';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = NetworkDetector;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output Formatter
|
|
3
|
+
* Formats outputs for createrawtransaction RPC calls
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
class OutputFormatter {
|
|
7
|
+
/**
|
|
8
|
+
* Format issue operation output
|
|
9
|
+
* @param {object} params - Issue parameters
|
|
10
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
11
|
+
*/
|
|
12
|
+
static formatIssueOutput(params) {
|
|
13
|
+
const {
|
|
14
|
+
asset_name,
|
|
15
|
+
asset_quantity,
|
|
16
|
+
units,
|
|
17
|
+
reissuable,
|
|
18
|
+
has_ipfs,
|
|
19
|
+
ipfs_hash
|
|
20
|
+
} = params;
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
issue: {
|
|
24
|
+
asset_name,
|
|
25
|
+
asset_quantity,
|
|
26
|
+
units,
|
|
27
|
+
reissuable: reissuable ? 1 : 0,
|
|
28
|
+
has_ipfs: has_ipfs ? 1 : 0,
|
|
29
|
+
ipfs_hash: ipfs_hash || ''
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Format issue unique operation output
|
|
36
|
+
* @param {object} params - Issue unique parameters
|
|
37
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
38
|
+
*/
|
|
39
|
+
static formatIssueUniqueOutput(params) {
|
|
40
|
+
const { root_name, asset_tags, ipfs_hashes } = params;
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
issue_unique: {
|
|
44
|
+
root_name,
|
|
45
|
+
asset_tags,
|
|
46
|
+
ipfs_hashes: ipfs_hashes || []
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Format issue restricted operation output
|
|
53
|
+
* @param {object} params - Issue restricted parameters
|
|
54
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
55
|
+
*/
|
|
56
|
+
static formatIssueRestrictedOutput(params) {
|
|
57
|
+
const {
|
|
58
|
+
asset_name,
|
|
59
|
+
asset_quantity,
|
|
60
|
+
verifier_string,
|
|
61
|
+
units,
|
|
62
|
+
reissuable,
|
|
63
|
+
has_ipfs,
|
|
64
|
+
ipfs_hash
|
|
65
|
+
} = params;
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
issue_restricted: {
|
|
69
|
+
asset_name,
|
|
70
|
+
asset_quantity,
|
|
71
|
+
verifier_string,
|
|
72
|
+
units,
|
|
73
|
+
reissuable: reissuable ? 1 : 0,
|
|
74
|
+
has_ipfs: has_ipfs ? 1 : 0,
|
|
75
|
+
ipfs_hash: ipfs_hash || ''
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Format issue qualifier operation output
|
|
82
|
+
* @param {object} params - Issue qualifier parameters
|
|
83
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
84
|
+
*/
|
|
85
|
+
static formatIssueQualifierOutput(params) {
|
|
86
|
+
const {
|
|
87
|
+
asset_name,
|
|
88
|
+
asset_quantity,
|
|
89
|
+
has_ipfs,
|
|
90
|
+
ipfs_hash
|
|
91
|
+
} = params;
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
issue_qualifier: {
|
|
95
|
+
asset_name,
|
|
96
|
+
asset_quantity,
|
|
97
|
+
has_ipfs: has_ipfs ? 1 : 0,
|
|
98
|
+
ipfs_hash: ipfs_hash || ''
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Format reissue operation output
|
|
105
|
+
* @param {object} params - Reissue parameters
|
|
106
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
107
|
+
*/
|
|
108
|
+
static formatReissueOutput(params) {
|
|
109
|
+
const {
|
|
110
|
+
asset_name,
|
|
111
|
+
asset_quantity,
|
|
112
|
+
reissuable,
|
|
113
|
+
new_ipfs
|
|
114
|
+
} = params;
|
|
115
|
+
|
|
116
|
+
const output = {
|
|
117
|
+
reissue: {
|
|
118
|
+
asset_name,
|
|
119
|
+
asset_quantity
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Optional parameters
|
|
124
|
+
if (reissuable !== undefined) {
|
|
125
|
+
output.reissue.reissuable = reissuable ? 1 : 0;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (new_ipfs) {
|
|
129
|
+
output.reissue.ipfs_hash = new_ipfs;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return output;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Format reissue restricted operation output
|
|
137
|
+
* @param {object} params - Reissue restricted parameters
|
|
138
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
139
|
+
*/
|
|
140
|
+
static formatReissueRestrictedOutput(params) {
|
|
141
|
+
const {
|
|
142
|
+
asset_name,
|
|
143
|
+
asset_quantity,
|
|
144
|
+
change_verifier,
|
|
145
|
+
new_verifier,
|
|
146
|
+
reissuable,
|
|
147
|
+
new_ipfs
|
|
148
|
+
} = params;
|
|
149
|
+
|
|
150
|
+
const output = {
|
|
151
|
+
reissue_restricted: {
|
|
152
|
+
asset_name,
|
|
153
|
+
asset_quantity
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
// Optional parameters
|
|
158
|
+
if (change_verifier && new_verifier) {
|
|
159
|
+
output.reissue_restricted.verifier_string = new_verifier;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (reissuable !== undefined) {
|
|
163
|
+
output.reissue_restricted.reissuable = reissuable ? 1 : 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (new_ipfs) {
|
|
167
|
+
output.reissue_restricted.ipfs_hash = new_ipfs;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
return output;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Format asset transfer output
|
|
175
|
+
* @param {string} assetName - Asset name
|
|
176
|
+
* @param {number} amount - Amount to transfer
|
|
177
|
+
* @returns {object} Formatted transfer output
|
|
178
|
+
*/
|
|
179
|
+
static formatTransferOutput(assetName, amount) {
|
|
180
|
+
return {
|
|
181
|
+
transfer: {
|
|
182
|
+
[assetName]: amount
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Format tag addresses operation output
|
|
189
|
+
* @param {object} params - Tag addresses parameters
|
|
190
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
191
|
+
*/
|
|
192
|
+
static formatTagAddressesOutput(params) {
|
|
193
|
+
const {
|
|
194
|
+
tag_name,
|
|
195
|
+
addresses,
|
|
196
|
+
asset_data
|
|
197
|
+
} = params;
|
|
198
|
+
|
|
199
|
+
return {
|
|
200
|
+
tag_addresses: {
|
|
201
|
+
tag_name,
|
|
202
|
+
addresses,
|
|
203
|
+
asset_data: asset_data || ''
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Format untag addresses operation output
|
|
210
|
+
* @param {object} params - Untag addresses parameters
|
|
211
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
212
|
+
*/
|
|
213
|
+
static formatUntagAddressesOutput(params) {
|
|
214
|
+
const {
|
|
215
|
+
tag_name,
|
|
216
|
+
addresses
|
|
217
|
+
} = params;
|
|
218
|
+
|
|
219
|
+
return {
|
|
220
|
+
untag_addresses: {
|
|
221
|
+
tag_name,
|
|
222
|
+
addresses
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Format freeze addresses operation output
|
|
229
|
+
* @param {object} params - Freeze addresses parameters
|
|
230
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
231
|
+
*/
|
|
232
|
+
static formatFreezeAddressesOutput(params) {
|
|
233
|
+
const {
|
|
234
|
+
asset_name,
|
|
235
|
+
addresses
|
|
236
|
+
} = params;
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
freeze_addresses: {
|
|
240
|
+
asset_name,
|
|
241
|
+
addresses
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Format unfreeze addresses operation output
|
|
248
|
+
* @param {object} params - Unfreeze addresses parameters
|
|
249
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
250
|
+
*/
|
|
251
|
+
static formatUnfreezeAddressesOutput(params) {
|
|
252
|
+
const {
|
|
253
|
+
asset_name,
|
|
254
|
+
addresses
|
|
255
|
+
} = params;
|
|
256
|
+
|
|
257
|
+
return {
|
|
258
|
+
unfreeze_addresses: {
|
|
259
|
+
asset_name,
|
|
260
|
+
addresses
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Format freeze asset operation output
|
|
267
|
+
* @param {string} assetName - Restricted asset name
|
|
268
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
269
|
+
*/
|
|
270
|
+
static formatFreezeAssetOutput(assetName) {
|
|
271
|
+
return {
|
|
272
|
+
freeze_asset: {
|
|
273
|
+
asset_name: assetName
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Format unfreeze asset operation output
|
|
280
|
+
* @param {string} assetName - Restricted asset name
|
|
281
|
+
* @returns {object} Formatted output for createrawtransaction
|
|
282
|
+
*/
|
|
283
|
+
static formatUnfreezeAssetOutput(assetName) {
|
|
284
|
+
return {
|
|
285
|
+
unfreeze_asset: {
|
|
286
|
+
asset_name: assetName
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
module.exports = OutputFormatter;
|