Getting memory 'memory access out of bounds' running nip44Decrypt in handleEvent callback #459
-
I am testing using Here is the error stack trace: panicked at bindings/nostr-sdk-js/src/client/mod.rs:787:1:
unexpected exception: JsValue(RuntimeError: memory access out of bounds
RuntimeError: memory access out of bounds
at wasm://wasm/00e8885a:wasm-function[4550]:0x21e230
at wasm://wasm/00e8885a:wasm-function[3777]:0x20fd3b
at passStringToWasm0 (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:58:15)
at module.exports.nip44Decrypt (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:613:22)
at Object.handleEvent (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/index.js:180:30)
at module.exports.__wbg_handleEvent_41d2742cd412fbae (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:12992:26)
at wasm://wasm/00e8885a:wasm-function[2398]:0x1e200d
at wasm://wasm/00e8885a:wasm-function[955]:0x14ba31
at wasm://wasm/00e8885a:wasm-function[4392]:0x21b25f
at wasm://wasm/00e8885a:wasm-function[4611]:0x21fb20)
Stack:
Error
at module.exports.__wbg_new_abda76e883ba8a5f (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:13296:17)
at wasm://wasm/00e8885a:wasm-function[5167]:0x229579
at wasm://wasm/00e8885a:wasm-function[1418]:0x17df38
at wasm://wasm/00e8885a:wasm-function[3667]:0x20e254
at wasm://wasm/00e8885a:wasm-function[2212]:0x1d54f2
at wasm://wasm/00e8885a:wasm-function[2398]:0x1e2695
at wasm://wasm/00e8885a:wasm-function[955]:0x14ba31
at wasm://wasm/00e8885a:wasm-function[4392]:0x21b25f
at wasm://wasm/00e8885a:wasm-function[4611]:0x21fb20
at __wbg_adapter_52 (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:248:10)
wasm://wasm/00e8885a:1
RuntimeError: unreachable
at wasm://wasm/00e8885a:wasm-function[1418]:0x17df5e
at wasm://wasm/00e8885a:wasm-function[3667]:0x20e254
at wasm://wasm/00e8885a:wasm-function[2212]:0x1d54f2
at wasm://wasm/00e8885a:wasm-function[2398]:0x1e2695
at wasm://wasm/00e8885a:wasm-function[955]:0x14ba31
at wasm://wasm/00e8885a:wasm-function[4392]:0x21b25f
at wasm://wasm/00e8885a:wasm-function[4611]:0x21fb20
at __wbg_adapter_52 (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:248:10)
at real (/Users/byoungdale/JavascriptProjects/nostr-private-messenger-client-cli/node_modules/.pnpm/@[email protected]/node_modules/@rust-nostr/nostr-sdk/pkg/nostr_sdk_js.js:173:20)
at node:internal/process/task_queues:140:7 Here is my script I'm testing with to reproduce: const fs = require("fs");
const {
Keys,
Client,
NostrSigner,
Filter,
PublicKey,
loadWasmAsync,
initLogger,
LogLevel,
nip44Decrypt,
} = require("@rust-nostr/nostr-sdk");
function getPValue(obj) {
const pTag = obj.tags.find((tag) => {
tag[0] === "p";
});
return pTag ? pTag[1] : null;
}
async function main() {
// CLI
let privateKeyPath = null;
let message = null;
let sendToPubKey = null;
let receive = false;
let generateKey = false;
let peerKeys = null;
console.dir(process.argv, { depth: null });
for (let i = 2; i < process.argv.length; i++) {
if (process.argv[i] === "--private-key-path") {
privateKeyPath = process.argv[i + 1];
i++;
} else if (process.argv[i] === "--message") {
message = process.argv[i + 1];
i++;
sendToPubKey = process.argv[i + 1];
i++;
} else if (process.argv[i] === "--receive") {
receive = true;
i++;
console.log(`process.argv[i]: ${process.argv[i]}`);
peerKeys = process.argv[i].split(",");
console.log(`process.argv[i]: ${process.argv[i]}`);
i++;
} else if (process.argv[i] === "--generate-key") {
generateKey = true;
}
}
if (privateKeyPath === null) {
console.error("Error: --private-key-path is required");
process.exit(1);
}
// NOSTR
await loadWasmAsync();
initLogger(LogLevel.debug());
let keys;
if (generateKey) {
// Generate new keys
keys = Keys.generate();
// Write private key to file
fs.writeFileSync(privateKeyPath, keys.secretKey.toBech32());
console.log(`Private key generated and stored in ${privateKeyPath}`);
return;
} else {
// Read private key from file
let privateKey = fs.readFileSync(privateKeyPath, "utf8").trim();
// Parse keys
keys = Keys.parse(privateKey);
}
// Hex keys
console.log("Public key (hex): ", keys.publicKey.toHex());
console.log("Secret key (hex): ", keys.secretKey.toHex());
// Bech32 keys
console.log("Public key (bech32): ", keys.publicKey.toBech32());
console.log("Secret key (bech32): ", keys.secretKey.toBech32());
let client;
try {
let signer = NostrSigner.keys(keys);
client = new Client(signer);
await client.addRelay("ws://127.0.0.1:8080");
} catch (e) {
console.error("Problem adding relay");
console.error(e);
process.exit(1);
}
try {
await client.connect();
} catch (e) {
console.error("Problem connecting to relay");
console.error(e);
process.exit(1);
}
// Send a message if one is provided
if (message && sendToPubKey) {
try {
const publicKey = PublicKey.parse(sendToPubKey); // Convert sendToPubKey to PublicKey object
await client.sendPrivateMsg(publicKey, message); // Pass publicKey as argument
} catch (e) {
console.error("Problem sending message");
console.error(e);
process.exit(1);
}
}
// get messages from these public keys
let filters = [];
peerKeys?.forEach((key) => {
let publicKey = PublicKey.parse(key);
const filter = new Filter().pubkey(publicKey).kind(1059).limit(10);
console.log("filter", filter.asJson());
filters.push(filter);
});
if (receive === true && filters.length === 0) {
console.error("No peer keys provided");
process.exit(1);
}
if (receive === false) {
console.log("All done.");
process.exit(1);
}
try {
await client.subscribe(filters);
} catch (e) {
console.error("Problem subscribing to relay");
console.error(e);
process.exit(1);
}
const handle = {
// Handle event
handleEvent: async (relayUrl, subscriptionId, event) => {
console.log(
"[",
subscriptionId,
"]",
"Received new event from",
relayUrl,
":",
event.asJson()
);
const verifyRes = event.verify();
console.log("verifyRes", verifyRes);
console.dir(event.tags[0].content());
const pValue = getPValue(event);
const senderPubKey = PublicKey.parse(event.tags[0].content());
console.log(
"Type and value of keys.secretKey: ",
typeof keys.secretKey,
keys.secretKey
);
console.log(
"Type and value of senderPubKey: ",
typeof senderPubKey,
senderPubKey
);
console.log("Type and value of event: ", typeof event, event);
// How the message is encrypted (aka sealed and giftwrapped)
// Using this to decide how to decrypt
// Reference: https://github.com/nostr-protocol/nips/blob/master/17.md
// {
// "id": "<usual hash>",
// "pubkey": randomPublicKey,
// "created_at": randomTimeUpTo2DaysInThePast(),
// "kind": 1059, // gift wrap
// "tags": [
// ["p", receiverPublicKey, "<relay-url>"] // receiver
// ],
// "content": nip44Encrypt(
// {
// "id": "<usual hash>",
// "pubkey": senderPublicKey,
// "created_at": randomTimeUpTo2DaysInThePast(),
// "kind": 13, // seal
// "tags": [], // no tags
// "content": nip44Encrypt(unsignedKind14, senderPrivateKey, receiverPublicKey),
// "sig": "<signed by senderPrivateKey>"
// },
// randomPrivateKey, receiverPublicKey
// ),
// "sig": "<signed by randomPrivateKey>"
// }
// !!!!!!!!!!! MEMORY OUT OF BOUND ERROR HERE !!!!!!!!!!!!
const unwrappedEvent = nip44Decrypt(keys.secretKey, senderPubKey, event);
console.dir(unwrappedEvent);
const unsealedRumor = nip44Decrypt(
keys.secretKey,
senderPubKey,
unwrappedEvent
);
console.dir(unsealedRumor);
},
// Handle relay message
handleMsg: async (relayUrl, message) => {
console.log("Received message from", relayUrl, message.asJson());
},
};
// @ts-ignore
client.handleNotifications(handle);
}
// example
// node index.js --private-key-path /path/to/private/key --message "Hello, world!" --receive
main(); You can generate a key real quick: node index.js --private-key-path ./client-1-key.txt --generate-key
node index.js --private-key-path ./client-2-key.txt --generate-key Then run in two terminals to quickly recreate: node index.js --private-key-path ./client-2-key.txt --message "Hello, from client 1" "CLIENT_2_PUBKEY" --receive "CLIENT_2_PUBKEY" client 2 node index.js --private-key-path ./client-2-key.txt --message "Hello, from client 2" "CLIENT_1_PUBKEY" --receive "CLIENT_1_PUBKEY" Any help would be great! |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 2 replies
-
Thanks, tomorrow I'll investigate. It's available a way to automatically decrypt Gift Wraps, without manually using let unwrapped = UnwrappedGift.fromGiftWrap(keys, event);
let sender = unwrapped.sender;
let rumor = unwrapped.rumor; nostr/bindings/nostr-sdk-js/examples/bot.js Lines 33 to 37 in 6e642ff |
Beta Was this translation helpful? Give feedback.
-
@yukibtc, I'd be interested in the root cause of my original error (even though the UnwrappedGift.fromGiftWrap worked). I know rust and javascript, but the wasm stuff is new. Do you have any pointers on how to troubleshoot it? |
Beta Was this translation helpful? Give feedback.
-
I should have found and fixed the issue: the allocated memory for the WebAssembly stack was only 1MiB, I increased it to 32MiB at aab96e3 |
Beta Was this translation helpful? Give feedback.
-
Just published |
Beta Was this translation helpful? Give feedback.
Thanks, tomorrow I'll investigate.
It's available a way to automatically decrypt Gift Wraps, without manually using
nip44Decrypt
:nostr/bindings/nostr-sdk-js/examples/bot.js
Lines 33 to 37 in 6e642ff