importjsonimportosimporttimeimporturllib.requestfromsymbolchain.CryptoTypesimportPrivateKeyfromsymbolchain.facade.NemFacadeimportNemFacadefromsymbolchain.ncimportAmountfromsymbolchain.nem.FeeCalculatorimportcalculate_transaction_feeNODE_URL=os.getenv('NODE_URL','http://libertalia.nemtest.net:7890')print(f'Using node {NODE_URL}')# Helper function to announce a transactiondefannounce_transaction(payload,label):announce_path='/transaction/announce'print(f'Announcing {label} to {announce_path}')request=urllib.request.Request(f'{NODE_URL}{announce_path}',data=payload.encode(),headers={'Content-Type':'application/json'},method='POST')withurllib.request.urlopen(request)asannounce_response:result=json.loads(announce_response.read().decode())print(f' Result: {result["message"]}')returnresult['message']# Helper function to wait for transaction confirmationdefwait_for_confirmation(tx_hash,label):status_path=f'/transaction/get?hash={tx_hash}'print(f'Waiting for {label} confirmation from {status_path}')is_confirmed=Falsefor_inrange(120):try:withurllib.request.urlopen(f'{NODE_URL}{status_path}')asstatus_response:confirmed=json.loads(status_response.read().decode())height=confirmed['meta']['height']print(f'{label} confirmed in block {height}')is_confirmed=Truebreakexcepturllib.error.HTTPError:print(' Transaction status: pending')time.sleep(1)ifnotis_confirmed:print(f'{label} confirmation took too long.')SIGNER_PRIVATE_KEY=os.getenv('SIGNER_PRIVATE_KEY','0000000000000000000000000000000000000000000000000000000000000000')signer_key_pair=NemFacade.KeyPair(PrivateKey(SIGNER_PRIVATE_KEY))RECIPIENT_ADDRESS=os.getenv('RECIPIENT_ADDRESS','TBULEAUG2CZQISUR442HWA6UAKGWIXHDABJVIPS4')MOSAIC_ID=os.getenv('MOSAIC_ID','company:token')MOSAIC_NAMESPACE,MOSAIC_NAME=MOSAIC_ID.split(':')QUANTITY=int(os.getenv('QUANTITY','100'))print(f'Sending mosaic {MOSAIC_ID}')print(f' Amount: {QUANTITY} units')facade=NemFacade('testnet')try:# Fetch the mosaic's divisibility and supplydefinition_path=f'/mosaic/definition?mosaicId={MOSAIC_ID}'print(f'Fetching mosaic definition from {definition_path}')withurllib.request.urlopen(f'{NODE_URL}{definition_path}')asresponse:definition=json.loads(response.read().decode())properties={prop['name']:prop['value']forpropindefinition['properties']}divisibility=int(properties['divisibility'])supply_path=f'/mosaic/supply?mosaicId={MOSAIC_ID}'print(f'Fetching mosaic supply from {supply_path}')withurllib.request.urlopen(f'{NODE_URL}{supply_path}')asresponse:supply=json.loads(response.read().decode())['supply']print(f' {MOSAIC_ID}: divisibility {divisibility}, supply {supply}')# Build the transactionatomic_quantity=QUANTITY*(10**divisibility)multiplier=1scaled_multiplier=multiplier*1_000_000transaction=facade.create_transaction_from_descriptor({'type':'transfer_transaction_v2','recipient_address':RECIPIENT_ADDRESS,'amount':scaled_multiplier,'mosaics':[{'mosaic':{'mosaic_id':{'namespace_id':{'name':MOSAIC_NAMESPACE},'name':MOSAIC_NAME},'amount':atomic_quantity}}]},signer_key_pair.public_key,0,2*60*60)# Calculate and attach the transaction feefee=calculate_transaction_fee(transaction,{MOSAIC_ID:{'supply':supply,'divisibility':divisibility}})transaction.fee=Amount(fee)print(f' Transaction fee: {fee/1_000_000} XEM')# 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))# Announce the transactionannounce_result=announce_transaction(json_payload,'transaction')# Wait for confirmationif'SUCCESS'==announce_result:transaction_hash=facade.hash_transaction(transaction)print(f'Transaction hash: {transaction_hash}')wait_for_confirmation(transaction_hash,'transaction')else:print(f'Transaction rejected: {announce_result}')exceptExceptionaserror:print(error)
import{PrivateKey}from'symbol-sdk';import{Address,NemFacade,calculateTransactionFee,descriptors,models}from'symbol-sdk/nem';constNODE_URL=process.env.NODE_URL||'http://libertalia.nemtest.net:7890';console.log('Using node',NODE_URL);// Helper function to announce a transactionasyncfunctionannounceTransaction(payload,label){constannouncePath='/transaction/announce';console.log(`Announcing ${label} to ${announcePath}`);constresponse=awaitfetch(`${NODE_URL}${announcePath}`,{method:'POST',headers:{'Content-Type':'application/json'},body:payload});if(!response.ok)thrownewError(`HTTP ${response.status}`);constresult=awaitresponse.json();console.log(' Result:',result.message);returnresult.message;}// Helper function to wait for transaction confirmationasyncfunctionwaitForConfirmation(transactionHash,label){conststatusPath=`/transaction/get?hash=${transactionHash}`;console.log(`Waiting for ${label} confirmation from`,statusPath);letisConfirmed=false;for(letattempt=1;120>=attempt;++attempt){constresponse=awaitfetch(`${NODE_URL}${statusPath}`);if(!response.ok){console.log(' Transaction status: pending');awaitnewPromise(resolve=>{setTimeout(resolve,1000);});}else{constconfirmed=awaitresponse.json();console.log(`${label} confirmed in block`,confirmed.meta.height);isConfirmed=true;break;}}if(!isConfirmed)console.warn(`${label} confirmation took too long.`);}constSIGNER_PRIVATE_KEY=process.env.SIGNER_PRIVATE_KEY||'0000000000000000000000000000000000000000000000000000000000000000';constsignerKeyPair=newNemFacade.KeyPair(newPrivateKey(SIGNER_PRIVATE_KEY));constRECIPIENT_ADDRESS=process.env.RECIPIENT_ADDRESS||'TBULEAUG2CZQISUR442HWA6UAKGWIXHDABJVIPS4';constMOSAIC_ID=process.env.MOSAIC_ID||'company:token';const[MOSAIC_NAMESPACE,MOSAIC_NAME]=MOSAIC_ID.split(':');constQUANTITY=parseInt(process.env.QUANTITY||'100',10);console.log('Sending mosaic',MOSAIC_ID);console.log(` Amount: ${QUANTITY} units`);constfacade=newNemFacade('testnet');try{// Fetch the mosaic's divisibility and supplyconstdefinitionPath=`/mosaic/definition?mosaicId=${MOSAIC_ID}`;console.log('Fetching mosaic definition from',definitionPath);constdefinitionResponse=awaitfetch(`${NODE_URL}${definitionPath}`);constdefinition=awaitdefinitionResponse.json();constproperties=Object.fromEntries(definition.properties.map(property=>[property.name,property.value]));constdivisibility=parseInt(properties.divisibility,10);constsupplyPath=`/mosaic/supply?mosaicId=${MOSAIC_ID}`;console.log('Fetching mosaic supply from',supplyPath);constsupplyResponse=awaitfetch(`${NODE_URL}${supplyPath}`);const{supply}=awaitsupplyResponse.json();console.log(` ${MOSAIC_ID}: divisibility ${divisibility},`,`supply ${supply}`);// Build the transactionconstatomicQuantity=QUANTITY*(10**divisibility);constmultiplier=1;constscaledMultiplier=multiplier*1_000_000;consttransaction=facade.createTransactionFromTypedDescriptor(newdescriptors.TransferTransactionV2Descriptor(newAddress(RECIPIENT_ADDRESS),newmodels.Amount(BigInt(scaledMultiplier)),undefined,[newdescriptors.SizePrefixedMosaicDescriptor(newdescriptors.MosaicDescriptor(newdescriptors.MosaicIdDescriptor(newdescriptors.NamespaceIdDescriptor(MOSAIC_NAMESPACE),MOSAIC_NAME),newmodels.Amount(BigInt(atomicQuantity))))]),signerKeyPair.publicKey,0n,2*60*60);// Calculate and attach the transaction feeconstfee=calculateTransactionFee(transaction,{[MOSAIC_ID]:{supply:BigInt(supply),divisibility}});transaction.fee=newmodels.Amount(fee);console.log(` Transaction fee: ${Number(fee)/1_000_000} XEM`);// 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,depth:null});// Announce the transactionconstannounceResult=awaitannounceTransaction(jsonPayload,'transaction');// Wait for confirmationif('SUCCESS'===announceResult){consttransactionHash=facade.hashTransaction(transaction).toString();console.log('Transaction hash:',transactionHash);awaitwaitForConfirmation(transactionHash,'transaction');}else{console.log('Transaction rejected:',announceResult);}}catch(e){console.error(e.message,'| Cause:',e.cause?.code??'unknown');}
//JAVA 21+//DEPS org.symbol:symbol-sdk:3.3.3import staticjava.nio.charset.StandardCharsets.UTF_8;importjava.io.IOException;importjava.net.URI;importjava.net.http.HttpClient;importjava.net.http.HttpRequest;importjava.net.http.HttpResponse;importjava.net.http.HttpResponse.BodyHandlers;importjava.util.List;importjava.util.Map;importcom.fasterxml.jackson.databind.JsonNode;importcom.fasterxml.jackson.databind.ObjectMapper;importorg.symbol.sdk.CryptoTypes;importorg.symbol.sdk.facade.NemFacade;importorg.symbol.sdk.nem.Address;importorg.symbol.sdk.nem.FeeCalculator;importorg.symbol.sdk.nem.FeeCalculator.MosaicInformation;importorg.symbol.sdk.nem.KeyPair;importorg.symbol.sdk.nem.NemTransactionFactory;importorg.symbol.sdk.nem.descriptors.MosaicDescriptor;importorg.symbol.sdk.nem.descriptors.MosaicIdDescriptor;importorg.symbol.sdk.nem.descriptors.NamespaceIdDescriptor;importorg.symbol.sdk.nem.descriptors.SizePrefixedMosaicDescriptor;importorg.symbol.sdk.nem.descriptors.TransferTransactionV2Descriptor;importorg.symbol.sdk.nem.models.Amount;importorg.symbol.sdk.nem.models.Transaction;publicfinalclassTransferMosaics{privatestaticfinalObjectMapperJSON_MAPPER=newObjectMapper();privatestaticfinalHttpClientHTTP_CLIENT=HttpClient.newHttpClient();privatefinalStringnodeUrl=System.getenv().getOrDefault("NODE_URL","http://libertalia.nemtest.net:7890");privatefinalNemFacadefacade=newNemFacade("testnet");privateStringannounceTransaction(finalStringpayload,finalStringlabel)throwsIOException,InterruptedException{finalStringannouncePath="/transaction/announce";System.out.printf("Announcing %s to %s%n",label,announcePath);finalHttpRequestrequest=HttpRequest.newBuilder(URI.create(nodeUrl+announcePath)).header("Content-Type","application/json").POST(HttpRequest.BodyPublishers.ofString(payload)).build();finalHttpResponse<String>response=HTTP_CLIENT.send(request,BodyHandlers.ofString());if(2!=response.statusCode()/100)thrownewIOException("HTTP "+response.statusCode());finalStringresult=JSON_MAPPER.readTree(response.body()).get("message").asText();System.out.printf(" Result: %s%n",result);returnresult;}privatevoidwaitForConfirmation(finalStringtransactionHash,finalStringlabel)throwsIOException,InterruptedException{finalStringstatusPath=String.format("/transaction/get?hash=%s",transactionHash);System.out.printf("Waiting for %s confirmation from %s%n",label,statusPath);booleanisConfirmed=false;for(intattempt=1;120>=attempt;++attempt){finalHttpRequestrequest=HttpRequest.newBuilder(URI.create(nodeUrl+statusPath)).GET().build();finalHttpResponse<String>response=HTTP_CLIENT.send(request,BodyHandlers.ofString());if(2!=response.statusCode()/100){System.out.println(" Transaction status: pending");Thread.sleep(1000);}else{finalJsonNodeconfirmed=JSON_MAPPER.readTree(response.body());System.out.printf("%s confirmed in block %s%n",label,confirmed.get("meta").get("height").asText());isConfirmed=true;break;}}if(!isConfirmed)System.out.printf("%s confirmation took too long.%n",label);}publicstaticvoidmain(finalString[]args){try{newTransferMosaics().run();}catch(finalExceptionex){System.out.println(null==ex.getMessage()?ex.toString():ex.getMessage());}}privatevoidrun()throwsIOException,InterruptedException{System.out.printf("Using node %s%n",nodeUrl);finalStringsignerPrivateKey=System.getenv().getOrDefault("SIGNER_PRIVATE_KEY","0".repeat(64));finalKeyPairsignerKeyPair=newKeyPair(newCryptoTypes.PrivateKey(signerPrivateKey));finalStringrecipientAddress=System.getenv().getOrDefault("RECIPIENT_ADDRESS","TBULEAUG2CZQISUR442HWA6UAKGWIXHDABJVIPS4");finalStringmosaicId=System.getenv().getOrDefault("MOSAIC_ID","company:token");finalString[]mosaicIdParts=mosaicId.split(":");finalStringmosaicNamespace=mosaicIdParts[0];finalStringmosaicName=mosaicIdParts[1];finalintquantity=Integer.parseInt(System.getenv().getOrDefault("QUANTITY","100"));System.out.printf("Sending mosaic %s%n",mosaicId);System.out.printf(" Amount: %d units%n",quantity);// Fetch the mosaic's divisibility and supplyfinalStringdefinitionPath=String.format("/mosaic/definition?mosaicId=%s",mosaicId);System.out.printf("Fetching mosaic definition from %s%n",definitionPath);finalHttpRequestdefinitionRequest=HttpRequest.newBuilder(URI.create(nodeUrl+definitionPath)).GET().build();finalHttpResponse<String>definitionResponse=HTTP_CLIENT.send(definitionRequest,BodyHandlers.ofString());finalJsonNodedefinition=JSON_MAPPER.readTree(definitionResponse.body());intdivisibility=0;for(finalJsonNodeproperty:definition.get("properties")){if("divisibility".equals(property.get("name").asText()))divisibility=property.get("value").asInt();}finalStringsupplyPath=String.format("/mosaic/supply?mosaicId=%s",mosaicId);System.out.printf("Fetching mosaic supply from %s%n",supplyPath);finalHttpRequestsupplyRequest=HttpRequest.newBuilder(URI.create(nodeUrl+supplyPath)).GET().build();finalHttpResponse<String>supplyResponse=HTTP_CLIENT.send(supplyRequest,BodyHandlers.ofString());finallongsupply=JSON_MAPPER.readTree(supplyResponse.body()).get("supply").asLong();System.out.printf(" %s: divisibility %d, supply %d%n",mosaicId,divisibility,supply);// Build the transactionfinallongatomicQuantity=Math.round(quantity*Math.pow(10,divisibility));finallongscaledMultiplier=1_000_000;finalMosaicIdDescriptormosaicIdDescriptor=newMosaicIdDescriptor(newNamespaceIdDescriptor(mosaicNamespace.getBytes(UTF_8)),mosaicName.getBytes(UTF_8));finalTransactiontransaction=facade.createTransactionFromTypedDescriptor(newTransferTransactionV2Descriptor(newAddress(recipientAddress),newAmount(scaledMultiplier),null,List.of(newSizePrefixedMosaicDescriptor(newMosaicDescriptor(mosaicIdDescriptor,newAmount(atomicQuantity))))),signerKeyPair.getPublicKey(),0,2*60*60);// Calculate and attach the transaction feefinallongfee=FeeCalculator.calculateTransactionFee(transaction,Map.of(mosaicId,newMosaicInformation(supply,divisibility)));transaction.setFee(newAmount(fee));System.out.printf(" Transaction fee: %s XEM%n",(double)fee/1_000_000);// Sign transaction and generate final payloadfinalCryptoTypes.Signaturesignature=facade.signTransaction(signerKeyPair,transaction);finalStringjsonPayload=NemTransactionFactory.attachSignature(transaction,signature);System.out.println("Built transaction:");System.out.println(JSON_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(transaction.toJson()));// Announce the transactionfinalStringannounceResult=announceTransaction(jsonPayload,"transaction");// Wait for confirmationif("SUCCESS".equals(announceResult)){finalStringtransactionHash=facade.hashTransaction(transaction).toString();System.out.printf("Transaction hash: %s%n",transactionHash);waitForConfirmation(transactionHash,"transaction");}else{System.out.printf("Transaction rejected: %s%n",announceResult);}}}
# Fetch the mosaic's divisibility and supplydefinition_path=f'/mosaic/definition?mosaicId={MOSAIC_ID}'print(f'Fetching mosaic definition from {definition_path}')withurllib.request.urlopen(f'{NODE_URL}{definition_path}')asresponse:definition=json.loads(response.read().decode())properties={prop['name']:prop['value']forpropindefinition['properties']}divisibility=int(properties['divisibility'])supply_path=f'/mosaic/supply?mosaicId={MOSAIC_ID}'print(f'Fetching mosaic supply from {supply_path}')withurllib.request.urlopen(f'{NODE_URL}{supply_path}')asresponse:supply=json.loads(response.read().decode())['supply']print(f' {MOSAIC_ID}: divisibility {divisibility}, supply {supply}')
// Fetch the mosaic's divisibility and supplyfinalStringdefinitionPath=String.format("/mosaic/definition?mosaicId=%s",mosaicId);System.out.printf("Fetching mosaic definition from %s%n",definitionPath);finalHttpRequestdefinitionRequest=HttpRequest.newBuilder(URI.create(nodeUrl+definitionPath)).GET().build();finalHttpResponse<String>definitionResponse=HTTP_CLIENT.send(definitionRequest,BodyHandlers.ofString());finalJsonNodedefinition=JSON_MAPPER.readTree(definitionResponse.body());intdivisibility=0;for(finalJsonNodeproperty:definition.get("properties")){if("divisibility".equals(property.get("name").asText()))divisibility=property.get("value").asInt();}finalStringsupplyPath=String.format("/mosaic/supply?mosaicId=%s",mosaicId);System.out.printf("Fetching mosaic supply from %s%n",supplyPath);finalHttpRequestsupplyRequest=HttpRequest.newBuilder(URI.create(nodeUrl+supplyPath)).GET().build();finalHttpResponse<String>supplyResponse=HTTP_CLIENT.send(supplyRequest,BodyHandlers.ofString());finallongsupply=JSON_MAPPER.readTree(supplyResponse.body()).get("supply").asLong();System.out.printf(" %s: divisibility %d, supply %d%n",mosaicId,divisibility,supply);
# Build the transactionatomic_quantity=QUANTITY*(10**divisibility)multiplier=1scaled_multiplier=multiplier*1_000_000transaction=facade.create_transaction_from_descriptor({'type':'transfer_transaction_v2','recipient_address':RECIPIENT_ADDRESS,'amount':scaled_multiplier,'mosaics':[{'mosaic':{'mosaic_id':{'namespace_id':{'name':MOSAIC_NAMESPACE},'name':MOSAIC_NAME},'amount':atomic_quantity}}]},signer_key_pair.public_key,0,2*60*60)
// Build the transactionconstatomicQuantity=QUANTITY*(10**divisibility);constmultiplier=1;constscaledMultiplier=multiplier*1_000_000;consttransaction=facade.createTransactionFromTypedDescriptor(newdescriptors.TransferTransactionV2Descriptor(newAddress(RECIPIENT_ADDRESS),newmodels.Amount(BigInt(scaledMultiplier)),undefined,[newdescriptors.SizePrefixedMosaicDescriptor(newdescriptors.MosaicDescriptor(newdescriptors.MosaicIdDescriptor(newdescriptors.NamespaceIdDescriptor(MOSAIC_NAMESPACE),MOSAIC_NAME),newmodels.Amount(BigInt(atomicQuantity))))]),signerKeyPair.publicKey,0n,2*60*60);
// Build the transactionfinallongatomicQuantity=Math.round(quantity*Math.pow(10,divisibility));finallongscaledMultiplier=1_000_000;finalMosaicIdDescriptormosaicIdDescriptor=newMosaicIdDescriptor(newNamespaceIdDescriptor(mosaicNamespace.getBytes(UTF_8)),mosaicName.getBytes(UTF_8));finalTransactiontransaction=facade.createTransactionFromTypedDescriptor(newTransferTransactionV2Descriptor(newAddress(recipientAddress),newAmount(scaledMultiplier),null,List.of(newSizePrefixedMosaicDescriptor(newMosaicDescriptor(mosaicIdDescriptor,newAmount(atomicQuantity))))),signerKeyPair.getPublicKey(),0,2*60*60);