Created
January 25, 2022 19:46
-
-
Save dashameter/592f7957e0a38e7a1a32b8dac5e8a5eb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Dash = require("dash"); | |
const CryptoJS = require("crypto-js"); | |
const secp256k1 = require("secp256k1-native"); | |
const dashcore = require("@dashevo/dashcore-lib"); | |
// sender, receiver must be friends (existing contactRequest documents on dpp) | |
// changing mnemonic requires adjusting or removing skipSynchronizationBeforeHeight | |
// const senderMnemonic = 'alert escape pear enhance mansion gossip seminar mansion enable salt bounce tumble'; // A-DashpayJS | |
// const receiverUsername = 'B-DashpayJS'; | |
// const senderMnemonic = 'catalog world quit margin supreme pony vacuum park inch soul daughter manage'; // B-DashpayJS | |
// const receiverUsername = 'A-DashpayJS'; | |
const senderMnemonic = | |
"soap minor liberty divert scrub comic mail stable crouch naive mouse fringe"; // high | |
const receiverUsername = "lowhangingfruit"; | |
const decryptCBCAES256 = (encrypted, secret, enc) => { | |
const encodings = { | |
hex: CryptoJS.enc.Hex, | |
utf8: CryptoJS.enc.Utf8, | |
base64: CryptoJS.enc.Base64, | |
}; | |
const key = CryptoJS.enc.Hex.parse(secret.toString("hex")); | |
const iv = CryptoJS.enc.Hex.parse(encrypted.slice(0, 16).toString("hex")); | |
const ciphertext = CryptoJS.enc.Hex.parse( | |
encrypted.slice(16, encrypted.length).toString("hex") | |
); | |
const encryptedCP = CryptoJS.lib.CipherParams.create({ | |
ciphertext, | |
formatter: CryptoJS.format.OpenSSL, // Optional, but required for encryptedCP.toString() | |
}); | |
const decryptedWA = CryptoJS.AES.decrypt(encryptedCP, key, { iv }); | |
const decrypted = decryptedWA.toString(encodings[enc]); | |
return decrypted; | |
}; | |
const clientOpts = { | |
network: "testnet", | |
// dapiAddresses: ["34.220.41.134", "18.236.216.191", "54.191.227.118"], | |
wallet: { | |
mnemonic: senderMnemonic, | |
unsafeOptions: { | |
skipSynchronizationBeforeHeight: 485512, | |
}, | |
}, | |
// apps: { | |
// dashpay: { | |
// contractId: "2DAncD4YTjfhSQZYrsQ659xbM7M5dNEkyfBEAg9SsS3W", | |
// }, | |
// }, | |
}; | |
const client = new Dash.Client(clientOpts); | |
const main = async () => { | |
client.account = await client.getWalletAccount(); | |
const senderIdentityId = client.account.identities.getIdentityIds()[0]; | |
const receiverDPNS = await client.platform.names.resolve( | |
`${receiverUsername}.dash` | |
); | |
const receiverIdentity = await client.platform.identities.get( | |
receiverDPNS.ownerId.toString() | |
); | |
console.log("receiverIdentity.toJSON() :>> ", receiverIdentity.toJSON()); | |
const contactRequests = await client.platform.documents.get( | |
"dashpay.contactRequest", | |
{ | |
limit: 1, | |
where: [ | |
["$ownerId", "==", receiverIdentity.getId()], | |
["toUserId", "==", senderIdentityId], | |
], | |
} | |
); | |
console.log("contactRequests :>> ", contactRequests[0].toJSON()); | |
// ECDH Shared Key / Diffie-Hellman Key Exchange | |
const receiverPublicKey = receiverIdentity.toJSON().publicKeys[0].data; | |
const senderPrivateKey = client.account.identities | |
.getIdentityHDKeyByIndex(0, 0) | |
.privateKey.toString(); | |
console.log("senderPrivateKey :>> ", senderPrivateKey); | |
const ctx = secp256k1.secp256k1_context_create( | |
secp256k1.secp256k1_context_SIGN | |
); | |
const sharedSecret = Buffer.alloc(32); | |
const point = Buffer.from(receiverPublicKey, "base64"); | |
const scalar = Buffer.from(senderPrivateKey, "hex"); | |
const pubkey64 = Buffer.alloc(64); | |
secp256k1.secp256k1_ec_pubkey_parse(ctx, pubkey64, point); | |
secp256k1.secp256k1_ecdh(ctx, sharedSecret, pubkey64, scalar, null); | |
console.log("sharedSecrect", sharedSecret.toString("hex")); | |
// CBC-AES-256 decryption | |
const { encryptedAccountLabel, encryptedPublicKey } = contactRequests[0].data; | |
console.log("encryptedAccountLabel :>> ", encryptedAccountLabel.length); | |
// Decrypt accountLabel | |
const decryptedAccountLabel = decryptCBCAES256( | |
encryptedAccountLabel, | |
sharedSecret, | |
"utf8" | |
); | |
console.log("decryptedAccountLabel :>> ", decryptedAccountLabel); | |
// Decrypt publicKey | |
const decryptedPublicKey = decryptCBCAES256( | |
encryptedPublicKey, | |
sharedSecret, | |
"hex" | |
); | |
console.log("decryptedPublicKey :>> ", decryptedPublicKey); | |
// Derive receiving address | |
const xpubkeyBuffers = Buffer.from(decryptedPublicKey, "hex"); | |
const parentFingerPrint = xpubkeyBuffers.slice(0, 4); | |
const chainCode = xpubkeyBuffers.slice(4, 36); | |
const publicKey = xpubkeyBuffers.slice(36, 69); | |
const depth = Buffer.alloc(1); | |
const childIndex = Buffer.alloc(4); | |
const xpubkey = dashcore.HDPublicKey.fromObject({ | |
parentFingerPrint, | |
chainCode, | |
publicKey, | |
network: "testnet", | |
depth, | |
childIndex, | |
}); | |
const receivingAddress = dashcore | |
.Address(xpubkey.publicKey, "testnet") | |
.toString(); | |
console.log("receivingAddress :>> ", receivingAddress); | |
const transaction = client.account.createTransaction({ | |
recipient: receivingAddress, | |
satoshis: 10000000, // 0.1 Dash | |
}); | |
const tx = await client.account.broadcastTransaction(transaction); | |
console.log("tx :>> ", tx); | |
}; | |
main() | |
.then(() => console.log("Success!")) | |
.catch((e) => console.error("Something went wrong:\n", e)) | |
.finally(() => client.disconnect()); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment