@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.
Files changed (58) hide show
  1. package/README.md +522 -0
  2. package/examples/01-create-root-asset.js +71 -0
  3. package/examples/02-create-sub-asset.js +79 -0
  4. package/examples/03-create-nfts.js +140 -0
  5. package/examples/04-reissue-asset.js +164 -0
  6. package/examples/05-create-qualifier-and-tag.js +209 -0
  7. package/examples/06-create-restricted-asset.js +223 -0
  8. package/examples/07-freeze-and-unfreeze.js +292 -0
  9. package/examples/08-query-assets.js +332 -0
  10. package/examples/09-wallet-integration.js +320 -0
  11. package/examples/README.md +319 -0
  12. package/package.json +43 -0
  13. package/src/NeuraiAssets.js +468 -0
  14. package/src/builders/BaseAssetTransactionBuilder.js +303 -0
  15. package/src/builders/FreezeAddressBuilder.js +271 -0
  16. package/src/builders/IssueQualifierBuilder.js +251 -0
  17. package/src/builders/IssueRestrictedBuilder.js +187 -0
  18. package/src/builders/IssueRootBuilder.js +173 -0
  19. package/src/builders/IssueSubBuilder.js +237 -0
  20. package/src/builders/IssueUniqueBuilder.js +255 -0
  21. package/src/builders/ReissueBuilder.js +246 -0
  22. package/src/builders/ReissueRestrictedBuilder.js +264 -0
  23. package/src/builders/TagAddressBuilder.js +243 -0
  24. package/src/builders/index.js +38 -0
  25. package/src/constants/assetTypes.js +23 -0
  26. package/src/constants/burnAddresses.js +65 -0
  27. package/src/constants/fees.js +61 -0
  28. package/src/constants/index.js +44 -0
  29. package/src/constants/networks.js +112 -0
  30. package/src/errors/AssetErrors.js +135 -0
  31. package/src/errors/ValidationErrors.js +87 -0
  32. package/src/errors/index.js +56 -0
  33. package/src/index.js +68 -0
  34. package/src/managers/BurnManager.js +222 -0
  35. package/src/managers/OutputOrderer.js +289 -0
  36. package/src/managers/OwnerTokenManager.js +265 -0
  37. package/src/managers/UTXOSelector.js +309 -0
  38. package/src/managers/index.js +16 -0
  39. package/src/queries/AssetQueries.js +447 -0
  40. package/src/queries/index.js +10 -0
  41. package/src/utils/amountConverter.js +115 -0
  42. package/src/utils/assetNameParser.js +203 -0
  43. package/src/utils/index.js +16 -0
  44. package/src/utils/networkDetector.js +144 -0
  45. package/src/utils/outputFormatter.js +292 -0
  46. package/src/validators/amountValidator.js +149 -0
  47. package/src/validators/assetNameValidator.js +296 -0
  48. package/src/validators/index.js +16 -0
  49. package/src/validators/ipfsValidator.js +101 -0
  50. package/src/validators/verifierValidator.js +146 -0
  51. package/tests/README.md +126 -0
  52. package/tests/integration/assetLifecycle.test.js +244 -0
  53. package/tests/mocks/rpcMock.js +156 -0
  54. package/tests/unit/NeuraiAssets.test.js +217 -0
  55. package/tests/unit/utils/amountConverter.test.js +171 -0
  56. package/tests/unit/utils/assetNameParser.test.js +203 -0
  57. package/tests/unit/validators/amountValidator.test.js +143 -0
  58. package/tests/unit/validators/assetNameValidator.test.js +228 -0
@@ -0,0 +1,332 @@
1
+ /**
2
+ * Example: Query Asset Information
3
+ *
4
+ * This example demonstrates how to query asset information from the blockchain.
5
+ * Includes various query methods for asset metadata, holders, balances, and more.
6
+ *
7
+ * All query methods are read-only and do not require signing transactions.
8
+ */
9
+
10
+ const NeuraiAssets = require('@neuraiproject/neurai-assets');
11
+
12
+ async function queryAssetMetadata() {
13
+ // Mock RPC function (replace with your actual RPC client)
14
+ const rpc = async (method, params) => {
15
+ console.log(`RPC Call: ${method}`, params);
16
+ // Your RPC implementation here
17
+ // Mock response:
18
+ return {
19
+ name: 'MYTOKEN',
20
+ amount: 1000000,
21
+ units: 2,
22
+ reissuable: true,
23
+ has_ipfs: true,
24
+ ipfs_hash: 'QmExample...'
25
+ };
26
+ };
27
+
28
+ // Initialize NeuraiAssets
29
+ const assets = new NeuraiAssets(rpc, {
30
+ network: 'xna',
31
+ addresses: ['NYourAddress1...'],
32
+ changeAddress: 'NChangeAddress...',
33
+ toAddress: 'NReceivingAddress...'
34
+ });
35
+
36
+ try {
37
+ console.log('=== Query Asset Metadata ===\n');
38
+
39
+ // Get complete asset data
40
+ const assetData = await assets.getAssetData('MYTOKEN');
41
+
42
+ console.log('Asset Information:');
43
+ console.log('- Name:', assetData.name);
44
+ console.log('- Total Supply:', assetData.amount);
45
+ console.log('- Decimals:', assetData.units);
46
+ console.log('- Reissuable:', assetData.reissuable ? 'Yes' : 'No (locked)');
47
+ console.log('- Has IPFS:', assetData.has_ipfs ? 'Yes' : 'No');
48
+ if (assetData.has_ipfs) {
49
+ console.log('- IPFS Hash:', assetData.ipfs_hash);
50
+ }
51
+
52
+ // Detect asset type
53
+ const assetType = assets.getAssetType('MYTOKEN');
54
+ console.log('- Type:', assetType);
55
+
56
+ } catch (error) {
57
+ console.error('Error querying asset:', error.message);
58
+
59
+ if (error.name === 'AssetNotFoundError') {
60
+ console.error('Asset does not exist on the blockchain');
61
+ }
62
+ }
63
+ }
64
+
65
+ // Example: List all assets
66
+ async function listAllAssets() {
67
+ const rpc = async (method, params) => {
68
+ console.log(`RPC Call: ${method}`, params);
69
+ // Mock: return list of assets
70
+ return ['MYTOKEN', 'ANOTHER', 'EXAMPLE'];
71
+ };
72
+
73
+ const assets = new NeuraiAssets(rpc, {
74
+ network: 'xna',
75
+ addresses: ['NYourAddress1...'],
76
+ changeAddress: 'NChangeAddress...',
77
+ toAddress: 'NReceivingAddress...'
78
+ });
79
+
80
+ try {
81
+ console.log('=== List All Assets ===\n');
82
+
83
+ // List all assets (simple list)
84
+ const allAssets = await assets.listAssets('*', false, 100, 0);
85
+ console.log(`Total assets found: ${allAssets.length}`);
86
+ console.log('Assets:', allAssets.slice(0, 10));
87
+
88
+ // Filter by pattern
89
+ console.log('\n=== Filter Assets by Pattern ===\n');
90
+ const myAssets = await assets.listAssets('MY*', false, 100, 0);
91
+ console.log('Assets starting with MY:', myAssets);
92
+
93
+ // Get detailed information
94
+ console.log('\n=== Get Detailed Information ===\n');
95
+ const detailed = await assets.listAssets('MYTOKEN', true, 1, 0);
96
+ console.log('Detailed data:', JSON.stringify(detailed, null, 2));
97
+
98
+ } catch (error) {
99
+ console.error('Error listing assets:', error.message);
100
+ }
101
+ }
102
+
103
+ // Example: Query wallet assets
104
+ async function queryMyAssets() {
105
+ const rpc = async (method, params) => {
106
+ console.log(`RPC Call: ${method}`, params);
107
+ // Mock: return wallet assets
108
+ return {
109
+ 'MYTOKEN': 1000.50,
110
+ 'ANOTHER': 500.25,
111
+ 'NFT#001': 1
112
+ };
113
+ };
114
+
115
+ const assets = new NeuraiAssets(rpc, {
116
+ network: 'xna',
117
+ addresses: ['NYourAddress1...'],
118
+ changeAddress: 'NChangeAddress...',
119
+ toAddress: 'NReceivingAddress...'
120
+ });
121
+
122
+ try {
123
+ console.log('=== My Asset Balances ===\n');
124
+
125
+ // Get all assets owned by wallet
126
+ const myAssets = await assets.listMyAssets();
127
+
128
+ console.log('Assets in wallet:');
129
+ for (const [assetName, balance] of Object.entries(myAssets)) {
130
+ console.log(`- ${assetName}: ${balance}`);
131
+ }
132
+
133
+ const totalAssets = Object.keys(myAssets).length;
134
+ console.log(`\nTotal different assets: ${totalAssets}`);
135
+
136
+ } catch (error) {
137
+ console.error('Error querying wallet assets:', error.message);
138
+ }
139
+ }
140
+
141
+ // Example: Query asset holders
142
+ async function queryAssetHolders() {
143
+ const rpc = async (method, params) => {
144
+ console.log(`RPC Call: ${method}`, params);
145
+ // Mock: return holders
146
+ return [
147
+ { address: 'NAddress1...', amount: 500.00 },
148
+ { address: 'NAddress2...', amount: 300.00 },
149
+ { address: 'NAddress3...', amount: 200.00 }
150
+ ];
151
+ };
152
+
153
+ const assets = new NeuraiAssets(rpc, {
154
+ network: 'xna',
155
+ addresses: ['NYourAddress1...'],
156
+ changeAddress: 'NChangeAddress...',
157
+ toAddress: 'NReceivingAddress...'
158
+ });
159
+
160
+ try {
161
+ console.log('=== Asset Holders ===\n');
162
+
163
+ const assetName = 'MYTOKEN';
164
+
165
+ // Get all holders
166
+ const holders = await assets.listAddressesByAsset(assetName);
167
+
168
+ console.log(`Holders of ${assetName}:`);
169
+ holders.forEach((holder, index) => {
170
+ console.log(`${index + 1}. ${holder.address}: ${holder.amount}`);
171
+ });
172
+
173
+ console.log(`\nTotal holders: ${holders.length}`);
174
+
175
+ // Get holder count only
176
+ console.log('\n=== Get Holder Count ===\n');
177
+ const count = await assets.listAddressesByAsset(assetName, true);
178
+ console.log(`Number of holders: ${count}`);
179
+
180
+ } catch (error) {
181
+ console.error('Error querying holders:', error.message);
182
+ }
183
+ }
184
+
185
+ // Example: Query address balances
186
+ async function queryAddressBalances() {
187
+ const rpc = async (method, params) => {
188
+ console.log(`RPC Call: ${method}`, params);
189
+ // Mock: return balances
190
+ return [
191
+ { asset: 'MYTOKEN', amount: 100.50 },
192
+ { asset: 'ANOTHER', amount: 50.25 },
193
+ { asset: 'NFT#001', amount: 1 }
194
+ ];
195
+ };
196
+
197
+ const assets = new NeuraiAssets(rpc, {
198
+ network: 'xna',
199
+ addresses: ['NYourAddress1...'],
200
+ changeAddress: 'NChangeAddress...',
201
+ toAddress: 'NReceivingAddress...'
202
+ });
203
+
204
+ try {
205
+ console.log('=== Address Asset Balances ===\n');
206
+
207
+ const address = 'NTestAddress...';
208
+
209
+ // Get all assets for an address
210
+ const balances = await assets.listAssetBalancesByAddress(address);
211
+
212
+ console.log(`Assets owned by ${address}:`);
213
+ balances.forEach((balance, index) => {
214
+ console.log(`${index + 1}. ${balance.asset}: ${balance.amount}`);
215
+ });
216
+
217
+ console.log(`\nTotal assets: ${balances.length}`);
218
+
219
+ } catch (error) {
220
+ console.error('Error querying address balances:', error.message);
221
+ }
222
+ }
223
+
224
+ // Example: Check existence and detect type
225
+ async function checkAssetExistence() {
226
+ const rpc = async (method, params) => {
227
+ console.log(`RPC Call: ${method}`, params);
228
+ return null; // Mock
229
+ };
230
+
231
+ const assets = new NeuraiAssets(rpc, {
232
+ network: 'xna',
233
+ addresses: ['NYourAddress1...'],
234
+ changeAddress: 'NChangeAddress...',
235
+ toAddress: 'NReceivingAddress...'
236
+ });
237
+
238
+ try {
239
+ console.log('=== Check Asset Existence ===\n');
240
+
241
+ const assetsToCheck = [
242
+ 'MYTOKEN',
243
+ 'MYTOKEN/SUB',
244
+ 'MYTOKEN#NFT001',
245
+ '#KYC_VERIFIED',
246
+ '$SECURITY',
247
+ 'MYTOKEN!',
248
+ 'NONEXISTENT'
249
+ ];
250
+
251
+ for (const assetName of assetsToCheck) {
252
+ const exists = await assets.assetExists(assetName);
253
+ const type = assets.getAssetType(assetName);
254
+
255
+ console.log(`${assetName}:`);
256
+ console.log(` Exists: ${exists ? 'Yes āœ“' : 'No āœ—'}`);
257
+ console.log(` Type: ${type}`);
258
+ console.log('');
259
+ }
260
+
261
+ } catch (error) {
262
+ console.error('Error:', error.message);
263
+ }
264
+ }
265
+
266
+ // Example: Advanced queries with pagination
267
+ async function advancedQueries() {
268
+ const rpc = async (method, params) => {
269
+ console.log(`RPC Call: ${method}`, params);
270
+ return [];
271
+ };
272
+
273
+ const assets = new NeuraiAssets(rpc, {
274
+ network: 'xna',
275
+ addresses: ['NYourAddress1...'],
276
+ changeAddress: 'NChangeAddress...',
277
+ toAddress: 'NReceivingAddress...'
278
+ });
279
+
280
+ try {
281
+ console.log('=== Advanced Queries with Pagination ===\n');
282
+
283
+ // Paginate through all assets
284
+ console.log('Getting all assets in pages of 100:');
285
+
286
+ let page = 0;
287
+ let allAssets = [];
288
+ let hasMore = true;
289
+
290
+ while (hasMore) {
291
+ const assets = await assets.listAssets('*', false, 100, page * 100);
292
+
293
+ if (assets.length === 0) {
294
+ hasMore = false;
295
+ } else {
296
+ allAssets = allAssets.concat(assets);
297
+ console.log(`Page ${page + 1}: ${assets.length} assets`);
298
+ page++;
299
+ }
300
+
301
+ // Safety limit
302
+ if (page > 10) break;
303
+ }
304
+
305
+ console.log(`\nTotal assets retrieved: ${allAssets.length}`);
306
+
307
+ } catch (error) {
308
+ console.error('Error:', error.message);
309
+ }
310
+ }
311
+
312
+ // Run the examples
313
+ console.log('=== Example 1: Query Asset Metadata ===\n');
314
+ queryAssetMetadata();
315
+
316
+ console.log('\n\n=== Example 2: List All Assets ===\n');
317
+ listAllAssets();
318
+
319
+ console.log('\n\n=== Example 3: Query Wallet Assets ===\n');
320
+ queryMyAssets();
321
+
322
+ console.log('\n\n=== Example 4: Query Asset Holders ===\n');
323
+ queryAssetHolders();
324
+
325
+ console.log('\n\n=== Example 5: Query Address Balances ===\n');
326
+ queryAddressBalances();
327
+
328
+ console.log('\n\n=== Example 6: Check Asset Existence ===\n');
329
+ checkAssetExistence();
330
+
331
+ console.log('\n\n=== Example 7: Advanced Queries ===\n');
332
+ advancedQueries();
@@ -0,0 +1,320 @@
1
+ /**
2
+ * Example: Complete Wallet Integration
3
+ *
4
+ * This example demonstrates complete integration with neurai-jswallet.
5
+ * Shows the full workflow from initialization to transaction broadcasting.
6
+ *
7
+ * This is the recommended way to use neurai-assets in production.
8
+ */
9
+
10
+ const NeuraiAssets = require('@neuraiproject/neurai-assets');
11
+ // const NeuraiWallet = require('@neuraiproject/neurai-jswallet'); // Uncomment in production
12
+
13
+ async function completeWalletIntegration() {
14
+ try {
15
+ console.log('=== Complete Wallet Integration Example ===\n');
16
+
17
+ // Step 1: Initialize wallet
18
+ console.log('Step 1: Initialize Wallet\n');
19
+
20
+ /*
21
+ // Uncomment in production:
22
+ const wallet = new NeuraiWallet(mnemonic, {
23
+ network: 'xna',
24
+ rpcUrl: 'http://localhost:9766',
25
+ rpcUser: 'your-rpc-user',
26
+ rpcPassword: 'your-rpc-password'
27
+ });
28
+
29
+ // Wait for wallet to sync
30
+ await wallet.sync();
31
+ console.log('āœ“ Wallet synced');
32
+ */
33
+
34
+ // Mock wallet for example
35
+ const wallet = {
36
+ rpc: async (method, params) => {
37
+ console.log(` RPC: ${method}`, params);
38
+ return null;
39
+ },
40
+ getAllAddresses: () => ['NAddress1...', 'NAddress2...'],
41
+ getChangeAddress: () => 'NChangeAddress...',
42
+ getReceivingAddress: () => 'NReceivingAddress...',
43
+ signTransaction: async (rawTx) => {
44
+ console.log(' Signing transaction...');
45
+ return 'signed-tx-hex';
46
+ },
47
+ broadcastTransaction: async (signedTx) => {
48
+ console.log(' Broadcasting transaction...');
49
+ return 'transaction-id-hash';
50
+ }
51
+ };
52
+
53
+ // Step 2: Initialize NeuraiAssets with wallet
54
+ console.log('\nStep 2: Initialize NeuraiAssets\n');
55
+
56
+ const assets = new NeuraiAssets(
57
+ wallet.rpc.bind(wallet), // Bind wallet's RPC function
58
+ {
59
+ network: 'xna',
60
+ addresses: wallet.getAllAddresses(),
61
+ changeAddress: wallet.getChangeAddress(),
62
+ toAddress: wallet.getReceivingAddress()
63
+ }
64
+ );
65
+
66
+ console.log('āœ“ NeuraiAssets initialized');
67
+ console.log(' Network:', 'xna');
68
+ console.log(' Addresses:', wallet.getAllAddresses().length);
69
+
70
+ // Step 3: Create an asset
71
+ console.log('\nStep 3: Create ROOT Asset\n');
72
+
73
+ const createResult = await assets.createRootAsset({
74
+ assetName: 'MYTOKEN',
75
+ quantity: 1000000,
76
+ units: 2,
77
+ reissuable: true,
78
+ hasIpfs: true,
79
+ ipfsHash: 'QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG'
80
+ });
81
+
82
+ console.log('āœ“ Transaction built');
83
+ console.log(' Fee:', createResult.fee, 'XNA');
84
+ console.log(' Burn:', createResult.burn, 'XNA');
85
+ console.log(' Owner Token:', createResult.metadata.ownerTokenName);
86
+
87
+ // Step 4: Sign the transaction
88
+ console.log('\nStep 4: Sign Transaction\n');
89
+
90
+ const signedTx = await wallet.signTransaction(createResult.rawTx);
91
+ console.log('āœ“ Transaction signed');
92
+
93
+ // Step 5: Broadcast the transaction
94
+ console.log('\nStep 5: Broadcast Transaction\n');
95
+
96
+ const txid = await wallet.broadcastTransaction(signedTx);
97
+ console.log('āœ“ Transaction broadcast');
98
+ console.log(' TXID:', txid);
99
+
100
+ // Step 6: Wait for confirmation (in production)
101
+ console.log('\nStep 6: Wait for Confirmation\n');
102
+ console.log(' Waiting for blockchain confirmation...');
103
+ console.log(' (In production, poll the transaction status)');
104
+
105
+ /*
106
+ // Uncomment in production:
107
+ let confirmed = false;
108
+ while (!confirmed) {
109
+ const tx = await wallet.getTransaction(txid);
110
+ if (tx.confirmations >= 1) {
111
+ confirmed = true;
112
+ console.log('āœ“ Transaction confirmed!');
113
+ } else {
114
+ await new Promise(resolve => setTimeout(resolve, 5000));
115
+ }
116
+ }
117
+ */
118
+
119
+ console.log('\nāœ“ Asset created successfully!');
120
+ console.log(' You now own: MYTOKEN and MYTOKEN!');
121
+
122
+ } catch (error) {
123
+ console.error('Error:', error.message);
124
+
125
+ // Handle specific errors
126
+ if (error.name === 'InsufficientFundsError') {
127
+ console.error('Not enough XNA in wallet');
128
+ console.error('Required:', error.required, 'XNA');
129
+ console.error('Available:', error.available, 'XNA');
130
+ } else if (error.name === 'AssetExistsError') {
131
+ console.error('Asset name already taken');
132
+ }
133
+ }
134
+ }
135
+
136
+ // Example: Create multiple assets in sequence
137
+ async function createMultipleAssets() {
138
+ const wallet = {
139
+ rpc: async (method, params) => {
140
+ console.log(` RPC: ${method}`);
141
+ return null;
142
+ },
143
+ getAllAddresses: () => ['NAddress1...'],
144
+ getChangeAddress: () => 'NChangeAddress...',
145
+ getReceivingAddress: () => 'NReceivingAddress...',
146
+ signTransaction: async (rawTx) => 'signed-tx',
147
+ broadcastTransaction: async (signedTx) => `txid-${Date.now()}`
148
+ };
149
+
150
+ const assets = new NeuraiAssets(wallet.rpc.bind(wallet), {
151
+ network: 'xna',
152
+ addresses: wallet.getAllAddresses(),
153
+ changeAddress: wallet.getChangeAddress(),
154
+ toAddress: wallet.getReceivingAddress()
155
+ });
156
+
157
+ try {
158
+ console.log('=== Create Multiple Assets ===\n');
159
+
160
+ // 1. Create ROOT asset
161
+ console.log('1. Creating ROOT asset: MYTOKEN');
162
+ const rootResult = await assets.createRootAsset({
163
+ assetName: 'MYTOKEN',
164
+ quantity: 1000000,
165
+ units: 2,
166
+ reissuable: true
167
+ });
168
+
169
+ const rootTxid = await wallet.broadcastTransaction(
170
+ await wallet.signTransaction(rootResult.rawTx)
171
+ );
172
+ console.log(' āœ“ TXID:', rootTxid);
173
+
174
+ // 2. Create SUB asset
175
+ console.log('\n2. Creating SUB asset: MYTOKEN/PREMIUM');
176
+ const subResult = await assets.createSubAsset({
177
+ assetName: 'MYTOKEN/PREMIUM',
178
+ quantity: 100000,
179
+ units: 0,
180
+ reissuable: true
181
+ });
182
+
183
+ const subTxid = await wallet.broadcastTransaction(
184
+ await wallet.signTransaction(subResult.rawTx)
185
+ );
186
+ console.log(' āœ“ TXID:', subTxid);
187
+
188
+ // 3. Create NFTs
189
+ console.log('\n3. Creating NFTs: MYTOKEN#GENESIS, MYTOKEN#001');
190
+ const nftResult = await assets.createUniqueAssets({
191
+ rootAssetName: 'MYTOKEN',
192
+ assetTags: [
193
+ { tag: 'GENESIS', hasIpfs: true, ipfsHash: 'QmGenesis...' },
194
+ { tag: '001', hasIpfs: true, ipfsHash: 'QmNFT001...' }
195
+ ]
196
+ });
197
+
198
+ const nftTxid = await wallet.broadcastTransaction(
199
+ await wallet.signTransaction(nftResult.rawTx)
200
+ );
201
+ console.log(' āœ“ TXID:', nftTxid);
202
+
203
+ console.log('\nāœ“ All assets created successfully!');
204
+
205
+ } catch (error) {
206
+ console.error('Error:', error.message);
207
+ }
208
+ }
209
+
210
+ // Example: Error handling
211
+ async function errorHandlingExample() {
212
+ const wallet = {
213
+ rpc: async (method, params) => {
214
+ if (method === 'listunspent') {
215
+ // Simulate insufficient funds
216
+ return [];
217
+ }
218
+ return null;
219
+ },
220
+ getAllAddresses: () => ['NAddress1...'],
221
+ getChangeAddress: () => 'NChangeAddress...',
222
+ getReceivingAddress: () => 'NReceivingAddress...'
223
+ };
224
+
225
+ const assets = new NeuraiAssets(wallet.rpc.bind(wallet), {
226
+ network: 'xna',
227
+ addresses: wallet.getAllAddresses(),
228
+ changeAddress: wallet.getChangeAddress(),
229
+ toAddress: wallet.getReceivingAddress()
230
+ });
231
+
232
+ try {
233
+ console.log('=== Error Handling Example ===\n');
234
+
235
+ const result = await assets.createRootAsset({
236
+ assetName: 'MYTOKEN',
237
+ quantity: 1000000,
238
+ units: 2,
239
+ reissuable: true
240
+ });
241
+
242
+ } catch (error) {
243
+ console.log('Caught error:', error.name);
244
+ console.log('Message:', error.message);
245
+
246
+ // Handle different error types
247
+ switch (error.name) {
248
+ case 'InsufficientFundsError':
249
+ console.log('\nšŸ’” Solution: Add more XNA to your wallet');
250
+ console.log(' Required:', error.required || 'N/A', 'XNA');
251
+ break;
252
+
253
+ case 'AssetExistsError':
254
+ console.log('\nšŸ’” Solution: Choose a different asset name');
255
+ console.log(' Taken name:', error.assetName);
256
+ break;
257
+
258
+ case 'OwnerTokenNotFoundError':
259
+ console.log('\nšŸ’” Solution: You need the owner token');
260
+ console.log(' Required token:', error.ownerTokenName);
261
+ break;
262
+
263
+ case 'InvalidAssetNameError':
264
+ console.log('\nšŸ’” Solution: Fix the asset name');
265
+ console.log(' Rules: 3-30 chars, A-Z 0-9 _ . only');
266
+ break;
267
+
268
+ default:
269
+ console.log('\nšŸ’” Solution: Check error message above');
270
+ }
271
+ }
272
+ }
273
+
274
+ // Example: Query and update configuration
275
+ async function dynamicConfiguration() {
276
+ const wallet = {
277
+ rpc: async (method, params) => null,
278
+ getAllAddresses: () => ['NAddress1...', 'NAddress2...'],
279
+ getChangeAddress: () => 'NChangeAddress...',
280
+ getReceivingAddress: () => 'NReceivingAddress...'
281
+ };
282
+
283
+ const assets = new NeuraiAssets(wallet.rpc.bind(wallet), {
284
+ network: 'xna',
285
+ addresses: wallet.getAllAddresses(),
286
+ changeAddress: wallet.getChangeAddress(),
287
+ toAddress: wallet.getReceivingAddress()
288
+ });
289
+
290
+ console.log('=== Dynamic Configuration ===\n');
291
+
292
+ console.log('Initial config:');
293
+ console.log(' Addresses:', wallet.getAllAddresses());
294
+ console.log(' Change:', wallet.getChangeAddress());
295
+
296
+ // Update configuration (e.g., after wallet generates new addresses)
297
+ console.log('\nUpdating configuration...');
298
+
299
+ assets.updateConfig({
300
+ addresses: ['NAddress1...', 'NAddress2...', 'NAddress3...'],
301
+ changeAddress: 'NNewChangeAddress...',
302
+ toAddress: 'NNewReceivingAddress...'
303
+ });
304
+
305
+ console.log('āœ“ Configuration updated');
306
+ console.log(' New addresses: 3');
307
+ }
308
+
309
+ // Run the examples
310
+ console.log('=== Example 1: Complete Integration ===\n');
311
+ completeWalletIntegration();
312
+
313
+ console.log('\n\n=== Example 2: Create Multiple Assets ===\n');
314
+ createMultipleAssets();
315
+
316
+ console.log('\n\n=== Example 3: Error Handling ===\n');
317
+ errorHandlingExample();
318
+
319
+ console.log('\n\n=== Example 4: Dynamic Configuration ===\n');
320
+ dynamicConfiguration();