-
-
Save EdamAme-x/c27ccb2c0f8a2a5ed6a80b27636ee0f1 to your computer and use it in GitHub Desktop.
Twitter x transaction id
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
import "./dom.js"; | |
// <meta name="twittter-site-verification" content="..." /> | |
const twitterSiteVerification = | |
"..."; | |
const selector = "[id^='loading-x-anim-']"; | |
const xTransactionId = () => { | |
let LW; | |
const decodeBase64ToUint8Array = (n) => | |
new Uint8Array(atob(n).split("").map((n) => n.charCodeAt(0))); | |
const encodeBytesToBase64 = (n) => | |
{ | |
return btoa(Array.from(n).map((n) => String.fromCharCode(n)).join("")).replace( | |
/=/g, | |
"", | |
); | |
} | |
const getTwitterSiteVerificationBytes = () => | |
decodeBase64ToUint8Array( | |
twitterSiteVerification, | |
); | |
const EW = () => { | |
const logo = | |
getElementChildren(document.querySelectorAll(selector))[0].childNodes[0] | |
.childNodes[1]; | |
LW = LW || | |
(logo && logo.getAttribute("d") || "").substring(9).split("C").map((n) => | |
n.replace(/[^\d]+/g, " ").trim().split(" ").map(Number) | |
); | |
return LW; | |
}; | |
const getElementChildren = (n) => | |
Array.from(n).map((n) => (n.parentElement?.["removeChild"](n), n)); | |
const createHiddenElement = () => { | |
const n = document["createElement"]("div"); | |
return document["body"]["append"](n), [n, () => getElementChildren([n])]; | |
}; | |
const conditionalXor = (n, t, r) => t ? n ^ r[0] : n; | |
const mc = (n, t, r) => { | |
{ | |
if (!n.animate) { | |
return; | |
} | |
const W = n.animate(Sc(t), 4096); | |
W.pause(); | |
W.currentTime = Math.round(r / 10) * 10; | |
} | |
}; | |
const toHex = (n) => (n < 16 ? "0" : "") + n["toString"](16); | |
const hc = (n, t, r, W) => { | |
{ | |
const c = n * (r - t) / 255 + t; | |
return W ? Math.floor(c) : c.toFixed(2); | |
} | |
}; | |
const Sc = (n) => ({ | |
color: [ | |
"#" + (toHex(n[0]) + n[0].toString(16)) + | |
(toHex(n[1]) + n[1].toString(16)) + | |
(toHex(n[2]) + n[2].toString(16)), | |
"#" + (toHex(n[3]) + n[3].toString(16)) + | |
(toHex(n[4]) + n[4].toString(16)) + | |
(toHex(n[5]) + n[5].toString(16)), | |
], | |
transform: ["rotate(0deg)", "rotate(" + hc(n[6], 60, 360, true) + "deg)"], | |
easing: "cubic-bezier(" + | |
Array.from(n.slice(7)).map((n, t) => hc(n, t % 2 ? -1 : 0, 1)).join() + | |
")", | |
}); | |
let qc; | |
let vc = []; | |
const Rc = (n) => { | |
if (!qc) { | |
const sn = EW(); | |
new Promise(() => { | |
{ | |
const c = new RTCPeerConnection(); | |
const channelId = Math.random().toString(36); | |
sc = c.createDataChannel(channelId); | |
c.createOffer().then((o) => { | |
try { | |
{ | |
const t = o.sdp || channelId; | |
vc = Array.from( | |
typeof [t[n[5] % 8] || "4", t[n[8] % 8]] == "string" | |
? new TextEncoder().encode([ | |
t[34 % 8] || "4", | |
t[n[8] % 8], | |
]) | |
: [t[n[5] % 8] || "4", t[n[8] % 8]], | |
); | |
c.close(); | |
} | |
} catch {} | |
})["catch"](() => 0); | |
} | |
})["catch"](() => 0); | |
const [vn, cleanup] = createHiddenElement(); | |
mc(vn, sn[n[30] % 16], n[41] % 16 * (n[18] % 16) * (n[6] % 16)); | |
const Qn = getComputedStyle(vn); | |
qc = Array.from(("" + Qn.color + Qn.transform).matchAll(/([\d.-]+)/g)) | |
.map((n) => Number(Number(n[0]).toFixed(2)).toString(16)).join("") | |
.replace(/[.-]/g, ""); | |
cleanup(); | |
} | |
return qc; | |
}; | |
return async (path, method) => { | |
// seconds since 2023/5/1 16:00:00 (GMT+9) | |
const nonce = Math.floor((Date.now() - 1682924400000) / 1000); | |
const nonceBuf = new Uint8Array(new Uint32Array([nonce]).buffer); | |
const twitterSiteVerificationBytes = getTwitterSiteVerificationBytes(); | |
const i = Rc(twitterSiteVerificationBytes); | |
return encodeBytesToBase64( | |
new Uint8Array([ | |
Math.random() * 256, | |
].concat( | |
Array.from(twitterSiteVerificationBytes), | |
Array.from(nonceBuf), | |
Array.from( | |
new Uint8Array( | |
await crypto.subtle.digest( | |
"sha-256", | |
new TextEncoder().encode( | |
[method, path, nonce].join("!") + "obfiowerehiring" + i, | |
), | |
), | |
), | |
).concat(vc).slice(0, 16), | |
[3], | |
)).map(conditionalXor), | |
); | |
}; | |
}; | |
const path = "/i/api/1.1/jot/client_event.json"; | |
const method = "POST"; | |
console.log( | |
await (await xTransactionId())( | |
path, | |
method, | |
), | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If you want the complete source code, please come to my dm.