importjsonimportosimporttimeimporturllib.requestfromsymbolchain.CryptoTypesimportPrivateKeyfromsymbolchain.facade.SymbolFacadeimportSymbolFacadefromsymbolchain.symbol.NetworkimportNetworkTimestampfromsymbolchain.symbol.IdGeneratorimport(generate_namespace_path,generate_mosaic_alias_id)fromsymbolchain.scimportAmount,NamespaceIdfromsymbolchain.symbol.NetworkimportAddressNODE_URL=os.getenv('NODE_URL','https://reference.symboltest.net:3001')print(f'Using node {NODE_URL}')SIGNER_PRIVATE_KEY=os.getenv('SIGNER_PRIVATE_KEY','0000000000000000000000000000000000000000000000000000000000000000')signer_key_pair=SymbolFacade.KeyPair(PrivateKey(SIGNER_PRIVATE_KEY))facade=SymbolFacade('testnet')signer_address=facade.network.public_key_to_address(signer_key_pair.public_key)print(f'Signer address: {signer_address}')namespace_name=os.getenv('NAMESPACE_NAME','my_namespace')print(f'Namespace name: {namespace_name}')namespace_id=generate_namespace_path(namespace_name)[-1]print(f'Namespace ID: {namespace_id} ({hex(namespace_id)})')# Target address to link the namespace totarget_address=Address(os.getenv('TARGET_ADDRESS','TCWYXKVYBMO4NBCUF3AXKJMXCGVSYQOS7ZG2TLI'))print(f'Target address: {target_address}')try:# Fetch current network timetime_path='/node/time'print(f'Fetching current network time from {time_path}')withurllib.request.urlopen(f'{NODE_URL}{time_path}')asresponse:response_json=json.loads(response.read().decode())receive_timestamp=(response_json['communicationTimestamps']['receiveTimestamp'])timestamp=NetworkTimestamp(int(receive_timestamp))print(f' Network time: {timestamp.timestamp} ms since nemesis')# Fetch recommended feesfee_path='/network/fees/transaction'print(f'Fetching recommended fees from {fee_path}')withurllib.request.urlopen(f'{NODE_URL}{fee_path}')asresponse:response_json=json.loads(response.read().decode())median_mult=response_json['medianFeeMultiplier']minimum_mult=response_json['minFeeMultiplier']fee_mult=max(median_mult,minimum_mult)print(f' Fee multiplier: {fee_mult}')# Build the alias transactiontransaction=facade.transaction_factory.create({'type':'address_alias_transaction_v1','signer_public_key':signer_key_pair.public_key,'deadline':timestamp.add_hours(2).timestamp,'namespace_id':namespace_id,'address':target_address,'alias_action':'link'})transaction.fee=Amount(fee_mult*transaction.size)# Sign transaction and generate final payloadsignature=facade.sign_transaction(signer_key_pair,transaction)json_payload=facade.transaction_factory.attach_signature(transaction,signature)print('Built transaction:')print(json.dumps(transaction.to_json(),indent=2))transaction_hash=facade.hash_transaction(transaction)print(f'Transaction hash: {transaction_hash}')# Announce transactionprint('Announcing address alias transaction to /transactions')request=urllib.request.Request(f'{NODE_URL}/transactions',data=json_payload.encode(),headers={'Content-Type':'application/json'},method='PUT')withurllib.request.urlopen(request)asresponse:print(f' Response: {response.read().decode()}')# Wait for confirmationprint('Waiting for transaction confirmation...')forattemptinrange(60):time.sleep(1)try:status_url=(f'{NODE_URL}/transactionStatus/{transaction_hash}')withurllib.request.urlopen(status_url)asresponse:status=json.loads(response.read().decode())print(f' Transaction status: {status["group"]}')ifstatus['group']=='confirmed':print('Address alias transaction confirmed in',attempt,'seconds')breakifstatus['group']=='failed':raiseException('Address alias transaction failed:',status['code'])excepturllib.error.HTTPError:print(' Transaction status: unknown')# Retrieve the namespace to verify the aliasnamespace_path=f'/namespaces/{namespace_id:x}'print(f'Fetching namespace information from {namespace_path}')withurllib.request.urlopen(f'{NODE_URL}{namespace_path}')asresponse:response_json=json.loads(response.read().decode())namespace_info=response_json['namespace']print('Alias information:')alias_type=namespace_info['alias']['type']print(f' Alias type: {alias_type}')ifalias_type==2:# ADDRESS typealiased_address=Address.from_decoded_address_hex_string(namespace_info['alias']['address'])print(f' Linked address: {aliased_address}')# Send a transfer using the alias instead of a raw addressprint(f'Using alias in transfer: {namespace_name}')# Encode the namespace ID as a recipient addressrecipient_id=generate_namespace_path(namespace_name)[-1]recipient_address=Address.from_namespace_id(NamespaceId(recipient_id),facade.network.identifier)transfer_tx=facade.transaction_factory.create({'type':'transfer_transaction_v1','signer_public_key':signer_key_pair.public_key,'deadline':timestamp.add_hours(2).timestamp,'recipient_address':recipient_address,'mosaics':[{'mosaic_id':generate_mosaic_alias_id('symbol.xym'),'amount':1_000_000# 1 XYM}]})print('Transfer transaction:')print(f' Recipient address (alias): {recipient_address}')exceptExceptionase:print(e)
import{PrivateKey}from'symbol-sdk';import{SymbolFacade,NetworkTimestamp,Address,models,generateNamespacePath,generateMosaicAliasId}from'symbol-sdk/symbol';constNODE_URL=process.env.NODE_URL||'https://reference.symboltest.net:3001';console.log('Using node',NODE_URL);constSIGNER_PRIVATE_KEY=process.env.SIGNER_PRIVATE_KEY||'0000000000000000000000000000000000000000000000000000000000000000';constsignerKeyPair=newSymbolFacade.KeyPair(newPrivateKey(SIGNER_PRIVATE_KEY));constfacade=newSymbolFacade('testnet');constsignerAddress=facade.network.publicKeyToAddress(signerKeyPair.publicKey);console.log('Signer address:',signerAddress.toString());constnamespaceName=process.env.NAMESPACE_NAME||'my_namespace';console.log('Namespace name:',namespaceName);constnsPath=generateNamespacePath(namespaceName);constnamespaceId=nsPath[nsPath.length-1];console.log('Namespace ID:',`${namespaceId} (0x${namespaceId.toString(16)})`);// Target address to link the namespace toconsttargetAddress=newSymbolFacade.Address(process.env.TARGET_ADDRESS||'TCWYXKVYBMO4NBCUF3AXKJMXCGVSYQOS7ZG2TLI');console.log('Target address:',targetAddress.toString());try{// Fetch current network timeconsttimePath='/node/time';console.log('Fetching current network time from',timePath);consttimeResponse=awaitfetch(`${NODE_URL}${timePath}`);consttimeJSON=awaittimeResponse.json();constreceiveTimestamp=timeJSON.communicationTimestamps.receiveTimestamp;consttimestamp=newNetworkTimestamp(receiveTimestamp);console.log(' Network time:',timestamp.timestamp,'ms since nemesis');// Fetch recommended feesconstfeePath='/network/fees/transaction';console.log('Fetching recommended fees from',feePath);constfeeResponse=awaitfetch(`${NODE_URL}${feePath}`);constfeeJSON=awaitfeeResponse.json();constmedianMult=feeJSON.medianFeeMultiplier;constminimumMult=feeJSON.minFeeMultiplier;constfeeMult=Math.max(medianMult,minimumMult);console.log(' Fee multiplier:',feeMult);// Build the alias transactionconsttransaction=facade.transactionFactory.create({type:'address_alias_transaction_v1',signerPublicKey:signerKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,namespaceId:namespaceId,address:targetAddress,aliasAction:'link'});transaction.fee=newmodels.Amount(feeMult*transaction.size);// Sign transaction and generate final payloadconstsignature=facade.signTransaction(signerKeyPair,transaction);constjsonPayload=facade.transactionFactory.static.attachSignature(transaction,signature);console.log('Built transaction:');console.dir(transaction.toJson(),{colors:true});consttransactionHash=facade.hashTransaction(transaction).toString();console.log('Transaction hash:',transactionHash);// Announce transactionconsole.log('Announcing address alias transaction to /transactions');constannounceResponse=awaitfetch(`${NODE_URL}/transactions`,{method:'PUT',headers:{'Content-Type':'application/json'},body:jsonPayload});console.log(' Response:',awaitannounceResponse.text());// Wait for confirmationconsole.log('Waiting for transaction confirmation...');for(letattempt=0;attempt<60;attempt++){awaitnewPromise(resolve=>setTimeout(resolve,1000));try{conststatusUrl=`${NODE_URL}/transactionStatus/${transactionHash}`;conststatusResponse=awaitfetch(statusUrl);if(!statusResponse.ok){console.log(' Transaction status: unknown');continue;}conststatus=awaitstatusResponse.json();console.log(' Transaction status:',status.group);if(status.group==='confirmed'){console.log('Address alias transaction confirmed in',attempt,'seconds');break;}if(status.group==='failed'){thrownewError(`Address alias transaction failed: ${status.code}`);}}catch(error){if(error.message.includes('failed:')){throwerror;}console.log(' Transaction status: unknown');}}// Retrieve the namespace to verify the aliasconstnamespacePath=`/namespaces/${namespaceId.toString(16)}`;console.log('Fetching namespace information from',namespacePath);constnamespaceResponse=awaitfetch(`${NODE_URL}${namespacePath}`);constnamespaceJSON=awaitnamespaceResponse.json();constnamespaceInfo=namespaceJSON.namespace;console.log('Alias information:');console.log(' Alias type:',namespaceInfo.alias.type);if(namespaceInfo.alias.type===2){// ADDRESS typeconstaliasedAddress=Address.fromDecodedAddressHexString(namespaceInfo.alias.address);console.log(' Linked address:',aliasedAddress.toString());}// Send a transfer using the alias instead of a raw addressconsole.log('Using alias in transfer:',namespaceName);// Encode the namespace ID as a recipient addressconstrecipientPath=generateNamespacePath(namespaceName);constrecipientId=recipientPath[recipientPath.length-1];constrecipientAddress=Address.fromNamespaceId(newmodels.NamespaceId(recipientId),facade.network.identifier);consttransferTx=facade.transactionFactory.create({type:'transfer_transaction_v1',signerPublicKey:signerKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,recipientAddress:recipientAddress,mosaics:[{mosaicId:generateMosaicAliasId('symbol.xym'),amount:1_000_000n// 1 XYM}]});console.log('Transfer transaction:');console.log(' Recipient address (alias):',recipientAddress.toString());}catch(e){console.error(e.message);}
namespace_name=os.getenv('NAMESPACE_NAME','my_namespace')print(f'Namespace name: {namespace_name}')namespace_id=generate_namespace_path(namespace_name)[-1]print(f'Namespace ID: {namespace_id} ({hex(namespace_id)})')# Target address to link the namespace totarget_address=Address(os.getenv('TARGET_ADDRESS','TCWYXKVYBMO4NBCUF3AXKJMXCGVSYQOS7ZG2TLI'))print(f'Target address: {target_address}')
constnamespaceName=process.env.NAMESPACE_NAME||'my_namespace';console.log('Namespace name:',namespaceName);constnsPath=generateNamespacePath(namespaceName);constnamespaceId=nsPath[nsPath.length-1];console.log('Namespace ID:',`${namespaceId} (0x${namespaceId.toString(16)})`);// Target address to link the namespace toconsttargetAddress=newSymbolFacade.Address(process.env.TARGET_ADDRESS||'TCWYXKVYBMO4NBCUF3AXKJMXCGVSYQOS7ZG2TLI');
# Fetch current network timetime_path='/node/time'print(f'Fetching current network time from {time_path}')withurllib.request.urlopen(f'{NODE_URL}{time_path}')asresponse:response_json=json.loads(response.read().decode())receive_timestamp=(response_json['communicationTimestamps']['receiveTimestamp'])timestamp=NetworkTimestamp(int(receive_timestamp))print(f' Network time: {timestamp.timestamp} ms since nemesis')# Fetch recommended feesfee_path='/network/fees/transaction'print(f'Fetching recommended fees from {fee_path}')withurllib.request.urlopen(f'{NODE_URL}{fee_path}')asresponse:response_json=json.loads(response.read().decode())median_mult=response_json['medianFeeMultiplier']minimum_mult=response_json['minFeeMultiplier']fee_mult=max(median_mult,minimum_mult)print(f' Fee multiplier: {fee_mult}')
try{// Fetch current network timeconsttimePath='/node/time';console.log('Fetching current network time from',timePath);consttimeResponse=awaitfetch(`${NODE_URL}${timePath}`);consttimeJSON=awaittimeResponse.json();constreceiveTimestamp=timeJSON.communicationTimestamps.receiveTimestamp;consttimestamp=newNetworkTimestamp(receiveTimestamp);console.log(' Network time:',timestamp.timestamp,'ms since nemesis');// Fetch recommended feesconstfeePath='/network/fees/transaction';console.log('Fetching recommended fees from',feePath);constfeeResponse=awaitfetch(`${NODE_URL}${feePath}`);constfeeJSON=awaitfeeResponse.json();constmedianMult=feeJSON.medianFeeMultiplier;constminimumMult=feeJSON.minFeeMultiplier;constfeeMult=Math.max(medianMult,minimumMult);
# Build the alias transactiontransaction=facade.transaction_factory.create({'type':'address_alias_transaction_v1','signer_public_key':signer_key_pair.public_key,'deadline':timestamp.add_hours(2).timestamp,'namespace_id':namespace_id,'address':target_address,'alias_action':'link'})transaction.fee=Amount(fee_mult*transaction.size)
// Build the alias transactionconsttransaction=facade.transactionFactory.create({type:'address_alias_transaction_v1',signerPublicKey:signerKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,namespaceId:namespaceId,address:targetAddress,aliasAction:'link'});
# Sign transaction and generate final payloadsignature=facade.sign_transaction(signer_key_pair,transaction)json_payload=facade.transaction_factory.attach_signature(transaction,signature)print('Built transaction:')print(json.dumps(transaction.to_json(),indent=2))transaction_hash=facade.hash_transaction(transaction)print(f'Transaction hash: {transaction_hash}')# Announce transactionprint('Announcing address alias transaction to /transactions')request=urllib.request.Request(f'{NODE_URL}/transactions',data=json_payload.encode(),headers={'Content-Type':'application/json'},method='PUT')withurllib.request.urlopen(request)asresponse:print(f' Response: {response.read().decode()}')
// Sign transaction and generate final payloadconstsignature=facade.signTransaction(signerKeyPair,transaction);constjsonPayload=facade.transactionFactory.static.attachSignature(transaction,signature);console.log('Built transaction:');console.dir(transaction.toJson(),{colors:true});consttransactionHash=facade.hashTransaction(transaction).toString();console.log('Transaction hash:',transactionHash);// Announce transactionconsole.log('Announcing address alias transaction to /transactions');constannounceResponse=awaitfetch(`${NODE_URL}/transactions`,{method:'PUT',headers:{'Content-Type':'application/json'},body:jsonPayload});
# Wait for confirmationprint('Waiting for transaction confirmation...')forattemptinrange(60):time.sleep(1)try:status_url=(f'{NODE_URL}/transactionStatus/{transaction_hash}')withurllib.request.urlopen(status_url)asresponse:status=json.loads(response.read().decode())print(f' Transaction status: {status["group"]}')ifstatus['group']=='confirmed':print('Address alias transaction confirmed in',attempt,'seconds')breakifstatus['group']=='failed':raiseException('Address alias transaction failed:',status['code'])excepturllib.error.HTTPError:print(' Transaction status: unknown')
# Retrieve the namespace to verify the aliasnamespace_path=f'/namespaces/{namespace_id:x}'print(f'Fetching namespace information from {namespace_path}')withurllib.request.urlopen(f'{NODE_URL}{namespace_path}')asresponse:response_json=json.loads(response.read().decode())namespace_info=response_json['namespace']print('Alias information:')alias_type=namespace_info['alias']['type']print(f' Alias type: {alias_type}')ifalias_type==2:# ADDRESS typealiased_address=Address.from_decoded_address_hex_string(namespace_info['alias']['address'])print(f' Linked address: {aliased_address}')
// Retrieve the namespace to verify the aliasconstnamespacePath=`/namespaces/${namespaceId.toString(16)}`;console.log('Fetching namespace information from',namespacePath);constnamespaceResponse=awaitfetch(`${NODE_URL}${namespacePath}`);constnamespaceJSON=awaitnamespaceResponse.json();constnamespaceInfo=namespaceJSON.namespace;console.log('Alias information:');console.log(' Alias type:',namespaceInfo.alias.type);if(namespaceInfo.alias.type===2){// ADDRESS typeconstaliasedAddress=Address.fromDecodedAddressHexString(namespaceInfo.alias.address);console.log(' Linked address:',aliasedAddress.toString());}
# Send a transfer using the alias instead of a raw addressprint(f'Using alias in transfer: {namespace_name}')# Encode the namespace ID as a recipient addressrecipient_id=generate_namespace_path(namespace_name)[-1]recipient_address=Address.from_namespace_id(NamespaceId(recipient_id),facade.network.identifier)transfer_tx=facade.transaction_factory.create({'type':'transfer_transaction_v1','signer_public_key':signer_key_pair.public_key,'deadline':timestamp.add_hours(2).timestamp,'recipient_address':recipient_address,'mosaics':[{'mosaic_id':generate_mosaic_alias_id('symbol.xym'),'amount':1_000_000# 1 XYM}]})print('Transfer transaction:')print(f' Recipient address (alias): {recipient_address}')
// Send a transfer using the alias instead of a raw addressconsole.log('Using alias in transfer:',namespaceName);// Encode the namespace ID as a recipient addressconstrecipientPath=generateNamespacePath(namespaceName);constrecipientId=recipientPath[recipientPath.length-1];constrecipientAddress=Address.fromNamespaceId(newmodels.NamespaceId(recipientId),facade.network.identifier);consttransferTx=facade.transactionFactory.create({type:'transfer_transaction_v1',signerPublicKey:signerKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,recipientAddress:recipientAddress,mosaics:[{mosaicId:generateMosaicAliasId('symbol.xym'),amount:1_000_000n// 1 XYM}]});console.log('Transfer transaction:');console.log(' Recipient address (alias):',recipientAddress.toString());
Using node https://reference.symboltest.net:3001
Signer address: TCHBDENCLKEBILBPWP3JPB2XNY64OE7PYHHE32I
Namespace name: nsaddr_1770541301
Namespace ID: 12901002700615428842 (0xb309919a9089aaea)
Target address: TCWYXKVYBMO4NBCUF3AXKJMXCGVSYQOS7ZG2TLI
Fetching current network time from /node/time
Network time: 103291999249 ms since nemesis
Fetching recommended fees from /network/fees/transaction
Fee multiplier: 100
Built transaction:
{
"signature": "88D2148FB1938012BE845D221363768ECBE903032940F37E7227728FD655B73D02B1A78E03F23C25E8F6F1B746C61E8BE3623C5D5F1E5D57BEBBA9A7F56B6604",
"signer_public_key": "3B6A27BCCEB6A42D62A3A8D02A6F0D73653215771DE243A63AC048A18B59DA29",
"version": 1,
"network": 152,
"type": 16974,
"fee": "16100",
"deadline": "103299199249",
"namespace_id": "12901002700615428842",
"address": "98AD8BAAB80B1DC684542EC175259711AB2C41D2FE4DA9AD",
"alias_action": 1
}
Transaction hash: 8312500644961DA08EF4899AE5160C2B810A8B506B74C58D3F4FCF257C309827
Announcing address alias transaction to /transactions
Response: {"message":"packet 9 was pushed to the network via /transactions"}
Waiting for transaction confirmation...
Transaction status: unconfirmed
Transaction status: confirmed
Address alias transaction confirmed in 17 seconds
Fetching namespace information from /namespaces/b309919a9089aaea
Alias information:
Alias type: 2
Linked address: TCWYXKVYBMO4NBCUF3AXKJMXCGVSYQOS7ZG2TLI
Using alias in transfer: nsaddr_1770541301
Transfer transaction:
Recipient address (alias): THVKVCMQTKIQTMYAAAAAAAAAAAAAAAAAAAAAAAA