Open silverpill opened 1 year ago
Good ideas. Thanks!
Here's my JavaScript function for generating payment requests (version 1):
import pako from "pako"
import { fromByteArray } from "base64-js"
function createMoneroPaymentRequestV1(data: PaymentData): string {
const dataJson = JSON.stringify(data, Object.keys(data).sort())
const encoder = new TextEncoder()
const dataBytes = encoder.encode(dataJson)
const dataCompressed = pako.gzip(dataBytes, { level: 9, windowBits: 31 })
const dataEncoded = fromByteArray(dataCompressed)
return `monero-request:1:${dataEncoded}`
}
It produces exactly the same code as the Python function in the example: https://github.com/lukeprofits/Monero_Payment_Request_Standard#example-python-function-to-create-a-monero-payment-request
One JS snippet in "Encoding A Monero Payment Request" section is not correct, I submitted a PR with a fix: #6
I implemented subscription code generation in javascript, and here are my observations:
json.dumps
by default produces "pretty" json:I think it would be better to use compact representation (without whitespaces):
json.dumps(json_data, separators=(',', ':'))
. This should reduce the size of the string, and might help implementers who use other programming languages.Both JavaScript and Python keep the order of keys unchanged during serialization. However, other languages may have different defaults, so it might be a good idea to sort the keys.
gzip.compress
is not deterministic. The output seems to be dependent on the current time, but this could be mitigated by settingmtime
parameter to 0:gzip.compress(json_str.encode('utf-8'), mtime=0)
After making this adjustment I successfully generated the samemonero-subscription
code with JavaScript.gzip compression is tricky to implement. There's a number of parameters and I found the right ones only by trial and error. I think we can keep it as is for now, but switch to a better algorithm in a future version.