importjsonimportosimporttimeimporturllib.errorimporturllib.requestfrombinasciiimporthexlifyfromsymbolchain.CryptoTypesimportPrivateKey,PublicKeyfromsymbolchain.facade.SymbolFacadeimportSymbolFacadefromsymbolchain.symbol.MessageEncoderimportMessageEncoderfromsymbolchain.symbol.NetworkimportNetworkTimestampfromsymbolchain.scimportAmount# ConfigurationNODE_URL=os.getenv("NODE_URL","https://reference.symboltest.net:3001")print(f"Using node {NODE_URL}")# Helper function to poll for confirmed transactiondefretrieve_confirmed_transaction(hash_value,label):print(f"Polling for {label} confirmation...")confirmed=Falseattempts=0max_attempts=60whilenotconfirmedandattempts<max_attempts:try:url=f"{NODE_URL}/transactions/confirmed/{hash_value}"withurllib.request.urlopen(url)asresponse:confirmed=Trueprint(f" {label} confirmed!")returnjson.loads(response.read().decode())excepturllib.error.HTTPError:# Transaction not yet confirmedpassattempts+=1time.sleep(2)ifnotconfirmed:raiseException(f"{label} not confirmed after {max_attempts} attempts")# Set up sender and recipient accountsfacade=SymbolFacade("testnet")sender_private_key_string=os.getenv("SENDER_PRIVATE_KEY","0000000000000000000000000000000000000000000000000000000000000000",)sender_key_pair=facade.KeyPair(PrivateKey(sender_private_key_string))sender_address=facade.network.public_key_to_address(sender_key_pair.public_key)recipient_private_key_string=os.getenv("RECIPIENT_PRIVATE_KEY","1111111111111111111111111111111111111111111111111111111111111111",)recipient_key_pair=facade.KeyPair(PrivateKey(recipient_private_key_string))recipient_address=facade.network.public_key_to_address(recipient_key_pair.public_key)print(f"Sender address: {sender_address}")print(f"Recipient address: {recipient_address}\n")# 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())timestamp=NetworkTimestamp(int(response_json['communicationTimestamps']['receiveTimestamp']))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}\n")# ===== PLAIN TEXT MESSAGE =====print("==> Sending Plain Text Message")# Create a plain text messageplain_message="Hello, Symbol!".encode("utf-8")print(f"Plain message: {plain_message.decode('utf-8')}")# Build transfer transaction with plain messageplain_transaction=facade.transaction_factory.create({"type":"transfer_transaction_v1","signer_public_key":sender_key_pair.public_key,"deadline":timestamp.add_hours(2).timestamp,"recipient_address":recipient_address,"mosaics":[],"message":plain_message,})plain_transaction.fee=Amount(fee_mult*plain_transaction.size)# Sign and announce the transactionplain_signature=facade.sign_transaction(sender_key_pair,plain_transaction)plain_json_payload=facade.transaction_factory.attach_signature(plain_transaction,plain_signature)plain_transaction_hash=facade.hash_transaction(plain_transaction)print(f"Transaction hash: {plain_transaction_hash}")plain_announce_request=urllib.request.Request(f"{NODE_URL}/transactions",data=plain_json_payload.encode("utf-8"),headers={"Content-Type":"application/json"},method="PUT",)withurllib.request.urlopen(plain_announce_request)asresponse:print(f"Plain message transaction announced\n")# ===== RECEIVING PLAIN TEXT MESSAGE =====print("<== Receiving Plain Text Message")# Wait for confirmationplain_tx_data=retrieve_confirmed_transaction(plain_transaction_hash,"Plain message transaction")# Decode plain message from confirmed transactionreceived_plain_message=bytes.fromhex(plain_tx_data["transaction"]["message"])print(f"Received plain message: {received_plain_message.decode('utf-8')}\n")# ===== ENCRYPTED MESSAGE =====print("==> Sending Encrypted Message")# Create a message encoder with sender's key pairsender_message_encoder=MessageEncoder(sender_key_pair)# Encrypt the message using recipient's public keysecret_message="This is a secret message!".encode("utf-8")encrypted_payload=sender_message_encoder.encode(recipient_key_pair.public_key,secret_message)print(f"Original message: {secret_message.decode('utf-8')}")print("Encrypted payload: "+hexlify(encrypted_payload).decode("utf-8"))# Build transfer transaction with encrypted messageencrypted_transaction=facade.transaction_factory.create({"type":"transfer_transaction_v1","signer_public_key":sender_key_pair.public_key,"deadline":timestamp.add_hours(2).timestamp,"recipient_address":recipient_address,"mosaics":[],"message":encrypted_payload,})encrypted_transaction.fee=Amount(fee_mult*encrypted_transaction.size)# Sign and announce the transactionencrypted_signature=facade.sign_transaction(sender_key_pair,encrypted_transaction)encrypted_json_payload=facade.transaction_factory.attach_signature(encrypted_transaction,encrypted_signature)encrypted_transaction_hash=facade.hash_transaction(encrypted_transaction)print(f"Transaction hash: {encrypted_transaction_hash}")encrypted_announce_request=urllib.request.Request(f"{NODE_URL}/transactions",data=encrypted_json_payload.encode("utf-8"),headers={"Content-Type":"application/json"},method="PUT",)withurllib.request.urlopen(encrypted_announce_request)asresponse:print(f"Encrypted message transaction announced\n")# ===== RECEIVING ENCRYPTED MESSAGE =====print("<== Receiving Encrypted Message")# Wait for confirmationencrypted_tx_data=retrieve_confirmed_transaction(encrypted_transaction_hash,"Encrypted message transaction")# Decode encrypted message using recipient's private keyrecipient_message_encoder=MessageEncoder(recipient_key_pair)received_encrypted_message=bytes.fromhex(encrypted_tx_data["transaction"]["message"])# Get sender's public key from the transactionsender_public_key_from_tx=PublicKey(encrypted_tx_data["transaction"]["signerPublicKey"])(is_decoded,decrypted_message)=recipient_message_encoder.try_decode(sender_public_key_from_tx,received_encrypted_message)ifis_decoded:message_text=decrypted_message.decode("utf-8")print(f"Recipient decrypted message: {message_text}")else:print(f"Recipient failed to decrypt message")
import{PrivateKey,PublicKey}from'symbol-sdk';import{SymbolFacade,NetworkTimestamp,models,MessageEncoder}from'symbol-sdk/symbol';// ConfigurationconstNODE_URL=process.env.NODE_URL||'https://reference.symboltest.net:3001';console.log('Using node',NODE_URL);// Helper function to poll for confirmed transactionasyncfunctionretrieveConfirmedTransaction(hash,label){console.log(`Polling for ${label} confirmation...`);letconfirmed=false;letattempts=0;constmaxAttempts=60;while(!confirmed&&attempts<maxAttempts){try{constresponse=awaitfetch(`${NODE_URL}/transactions/confirmed/${hash}`);if(response.ok){confirmed=true;console.log(` ${label} confirmed!`);returnawaitresponse.json();}}catch(error){// Transaction not yet confirmed}attempts++;awaitnewPromise(resolve=>setTimeout(resolve,2000));}if(!confirmed){thrownewError(`${label} not confirmed after ${maxAttempts} attempts`);}}// Set up sender and recipient accountsconstfacade=newSymbolFacade('testnet');constsenderPrivateKeyString=process.env.SENDER_PRIVATE_KEY||'0000000000000000000000000000000000000000000000000000000000000000';constsenderKeyPair=newSymbolFacade.KeyPair(newPrivateKey(senderPrivateKeyString));constsenderAddress=facade.network.publicKeyToAddress(senderKeyPair.publicKey);constrecipientPrivateKeyString=process.env.RECIPIENT_PRIVATE_KEY||'1111111111111111111111111111111111111111111111111111111111111111';constrecipientKeyPair=newSymbolFacade.KeyPair(newPrivateKey(recipientPrivateKeyString));constrecipientAddress=facade.network.publicKeyToAddress(recipientKeyPair.publicKey);console.log('Sender address:',senderAddress.toString());console.log('Recipient address:',recipientAddress.toString(),'\n');// Fetch current network timeconsttimePath='/node/time';console.log('Fetching current network time from',timePath);consttimeResponse=awaitfetch(`${NODE_URL}${timePath}`);consttimeJSON=awaittimeResponse.json();consttimestamp=newNetworkTimestamp(timeJSON.communicationTimestamps.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,'\n');// ===== PLAIN TEXT MESSAGE =====console.log('==> Sending Plain Text Message');// Create a plain text messageconstplainMessage=newTextEncoder().encode('Hello, Symbol!');console.log('Plain message:',newTextDecoder().decode(plainMessage));// Build transfer transaction with plain messageconstplainTransaction=facade.transactionFactory.create({type:'transfer_transaction_v1',signerPublicKey:senderKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,recipientAddress:recipientAddress.toString(),mosaics:[],message:plainMessage});plainTransaction.fee=newmodels.Amount(feeMult*plainTransaction.size);// Sign and announce the transactionconstplainSignature=facade.signTransaction(senderKeyPair,plainTransaction);constplainJsonPayload=facade.transactionFactory.static.attachSignature(plainTransaction,plainSignature);constplainTransactionHash=facade.hashTransaction(plainTransaction).toString();console.log('Transaction hash:',plainTransactionHash);awaitfetch(`${NODE_URL}/transactions`,{method:'PUT',headers:{'Content-Type':'application/json'},body:plainJsonPayload});console.log('Plain message transaction announced\n');// ===== RECEIVING PLAIN TEXT MESSAGE =====console.log('<== Receiving Plain Text Message');// Wait for confirmationconstplainTxData=awaitretrieveConfirmedTransaction(plainTransactionHash,'Plain message transaction');// Decode plain message from confirmed transactionconstreceivedPlainMessage=Buffer.from(plainTxData.transaction.message,'hex');console.log('Received plain message:',newTextDecoder().decode(receivedPlainMessage),'\n');// ===== ENCRYPTED MESSAGE =====console.log('==> Sending Encrypted Message');// Create a message encoder with sender's key pairconstsenderMessageEncoder=newMessageEncoder(senderKeyPair);// Encrypt the message using recipient's public keyconstsecretMessage=newTextEncoder().encode('This is a secret message!');constencryptedPayload=senderMessageEncoder.encode(recipientKeyPair.publicKey,secretMessage);console.log('Original message:',newTextDecoder().decode(secretMessage));consthex=Buffer.from(encryptedPayload).toString('hex');console.log('Encrypted payload:',hex);// Build transfer transaction with encrypted messageconstencryptedTransaction=facade.transactionFactory.create({type:'transfer_transaction_v1',signerPublicKey:senderKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,recipientAddress:recipientAddress.toString(),mosaics:[],message:encryptedPayload});encryptedTransaction.fee=newmodels.Amount(feeMult*encryptedTransaction.size);// Sign and announce the transactionconstencryptedSignature=facade.signTransaction(senderKeyPair,encryptedTransaction);constencryptedJsonPayload=facade.transactionFactory.static.attachSignature(encryptedTransaction,encryptedSignature);constencryptedTransactionHash=facade.hashTransaction(encryptedTransaction).toString();console.log('Transaction hash:',encryptedTransactionHash);awaitfetch(`${NODE_URL}/transactions`,{method:'PUT',headers:{'Content-Type':'application/json'},body:encryptedJsonPayload});console.log('Encrypted message transaction announced\n');// ===== RECEIVING ENCRYPTED MESSAGE =====console.log('<== Receiving Encrypted Message');// Wait for confirmationconstencryptedTxData=awaitretrieveConfirmedTransaction(encryptedTransactionHash,'Encrypted message transaction');// Decode encrypted message using recipient's private keyconstrecipientMessageEncoder=newMessageEncoder(recipientKeyPair);constreceivedEncryptedMessage=Buffer.from(encryptedTxData.transaction.message,'hex');// Get sender's public key from the transactionconstsenderPublicKeyFromTx=newPublicKey(encryptedTxData.transaction.signerPublicKey);constresult=recipientMessageEncoder.tryDecode(senderPublicKeyFromTx,receivedEncryptedMessage);if(result.isDecoded){console.log('Recipient decrypted message:',newTextDecoder().decode(result.message));}else{console.log('Recipient failed to decrypt message');}
# Set up sender and recipient accountsfacade=SymbolFacade("testnet")sender_private_key_string=os.getenv("SENDER_PRIVATE_KEY","0000000000000000000000000000000000000000000000000000000000000000",)sender_key_pair=facade.KeyPair(PrivateKey(sender_private_key_string))sender_address=facade.network.public_key_to_address(sender_key_pair.public_key)recipient_private_key_string=os.getenv("RECIPIENT_PRIVATE_KEY","1111111111111111111111111111111111111111111111111111111111111111",)recipient_key_pair=facade.KeyPair(PrivateKey(recipient_private_key_string))recipient_address=facade.network.public_key_to_address(recipient_key_pair.public_key)print(f"Sender address: {sender_address}")print(f"Recipient address: {recipient_address}\n")
// Set up sender and recipient accountsconstfacade=newSymbolFacade('testnet');constsenderPrivateKeyString=process.env.SENDER_PRIVATE_KEY||'0000000000000000000000000000000000000000000000000000000000000000';constsenderKeyPair=newSymbolFacade.KeyPair(newPrivateKey(senderPrivateKeyString));constsenderAddress=facade.network.publicKeyToAddress(senderKeyPair.publicKey);constrecipientPrivateKeyString=process.env.RECIPIENT_PRIVATE_KEY||'1111111111111111111111111111111111111111111111111111111111111111';constrecipientKeyPair=newSymbolFacade.KeyPair(newPrivateKey(recipientPrivateKeyString));constrecipientAddress=facade.network.publicKeyToAddress(recipientKeyPair.publicKey);console.log('Sender address:',senderAddress.toString());console.log('Recipient address:',recipientAddress.toString(),'\n');
print("==> Sending Plain Text Message")# Create a plain text messageplain_message="Hello, Symbol!".encode("utf-8")print(f"Plain message: {plain_message.decode('utf-8')}")# Build transfer transaction with plain messageplain_transaction=facade.transaction_factory.create({"type":"transfer_transaction_v1","signer_public_key":sender_key_pair.public_key,"deadline":timestamp.add_hours(2).timestamp,"recipient_address":recipient_address,"mosaics":[],"message":plain_message,})
console.log('==> Sending Plain Text Message');// Create a plain text messageconstplainMessage=newTextEncoder().encode('Hello, Symbol!');console.log('Plain message:',newTextDecoder().decode(plainMessage));// Build transfer transaction with plain messageconstplainTransaction=facade.transactionFactory.create({type:'transfer_transaction_v1',signerPublicKey:senderKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,recipientAddress:recipientAddress.toString(),mosaics:[],message:plainMessage});
print("==> Sending Encrypted Message")# Create a message encoder with sender's key pairsender_message_encoder=MessageEncoder(sender_key_pair)# Encrypt the message using recipient's public keysecret_message="This is a secret message!".encode("utf-8")encrypted_payload=sender_message_encoder.encode(recipient_key_pair.public_key,secret_message)print(f"Original message: {secret_message.decode('utf-8')}")print("Encrypted payload: "+hexlify(encrypted_payload).decode("utf-8"))# Build transfer transaction with encrypted messageencrypted_transaction=facade.transaction_factory.create({"type":"transfer_transaction_v1","signer_public_key":sender_key_pair.public_key,"deadline":timestamp.add_hours(2).timestamp,"recipient_address":recipient_address,"mosaics":[],"message":encrypted_payload,})
console.log('==> Sending Encrypted Message');// Create a message encoder with sender's key pairconstsenderMessageEncoder=newMessageEncoder(senderKeyPair);// Encrypt the message using recipient's public keyconstsecretMessage=newTextEncoder().encode('This is a secret message!');constencryptedPayload=senderMessageEncoder.encode(recipientKeyPair.publicKey,secretMessage);console.log('Original message:',newTextDecoder().decode(secretMessage));consthex=Buffer.from(encryptedPayload).toString('hex');console.log('Encrypted payload:',hex);// Build transfer transaction with encrypted messageconstencryptedTransaction=facade.transactionFactory.create({type:'transfer_transaction_v1',signerPublicKey:senderKeyPair.publicKey.toString(),deadline:timestamp.addHours(2).timestamp,recipientAddress:recipientAddress.toString(),mosaics:[],message:encryptedPayload});
print("<== Receiving Encrypted Message")# Wait for confirmationencrypted_tx_data=retrieve_confirmed_transaction(encrypted_transaction_hash,"Encrypted message transaction")# Decode encrypted message using recipient's private keyrecipient_message_encoder=MessageEncoder(recipient_key_pair)received_encrypted_message=bytes.fromhex(encrypted_tx_data["transaction"]["message"])# Get sender's public key from the transactionsender_public_key_from_tx=PublicKey(encrypted_tx_data["transaction"]["signerPublicKey"])(is_decoded,decrypted_message)=recipient_message_encoder.try_decode(sender_public_key_from_tx,received_encrypted_message)ifis_decoded:message_text=decrypted_message.decode("utf-8")print(f"Recipient decrypted message: {message_text}")else:print(f"Recipient failed to decrypt message")
console.log('<== Receiving Encrypted Message');// Wait for confirmationconstencryptedTxData=awaitretrieveConfirmedTransaction(encryptedTransactionHash,'Encrypted message transaction');// Decode encrypted message using recipient's private keyconstrecipientMessageEncoder=newMessageEncoder(recipientKeyPair);constreceivedEncryptedMessage=Buffer.from(encryptedTxData.transaction.message,'hex');// Get sender's public key from the transactionconstsenderPublicKeyFromTx=newPublicKey(encryptedTxData.transaction.signerPublicKey);constresult=recipientMessageEncoder.tryDecode(senderPublicKeyFromTx,receivedEncryptedMessage);if(result.isDecoded){console.log('Recipient decrypted message:',newTextDecoder().decode(result.message));}else{console.log('Recipient failed to decrypt message');}