Skip to content

Instantly share code, notes, and snippets.

@rubpy
Created January 12, 2025 03:02
Show Gist options
  • Save rubpy/d1c4628d597b3af649ead34aa76b8adc to your computer and use it in GitHub Desktop.
Save rubpy/d1c4628d597b3af649ead34aa76b8adc to your computer and use it in GitHub Desktop.
(function (rpcEndpoint) {
if (typeof rpcEndpoint !== "string" || !rpcEndpoint.length) return -1;
rpcEndpoint = rpcEndpoint.trim();
const wsEndpoint = rpcEndpoint.replace(/^http(s?)/gm, "ws$1");
const root = document.getElementById('root');
if (!root) return -2;
const reactId = Object.keys(root).find(s => s.startsWith("__reactContainer"));
if (root[reactId] === null || typeof root[reactId] !== "object" || !root[reactId].stateNode) return -2;
let ctx = root[reactId].stateNode;
if (!ctx.current || !ctx.current.child || !ctx.current.child.alternate || !ctx.current.child.alternate.dependencies) return -3;
ctx = ctx.current.child.alternate.dependencies;
if (!ctx.firstContext || !ctx.firstContext.context || !ctx.firstContext.context._currentValue) return -4;
ctx = ctx.firstContext.context._currentValue;
const localStorageEndpointKey = "connectionEndpts";
if (!localStorage.getItem(localStorageEndpointKey)) {
localStorage.setItem(localStorageEndpointKey, JSON.stringify(rpcEndpoint));
}
if (ctx.endpoint && typeof ctx.endpoint === "string") {
ctx.endpoint = rpcEndpoint;
}
const _hijackWs = function (wsEndpoint) {
if (!this || !this.webSocketFactory || this.__h_webSocketFactory) return;
this.__h_webSocketFactory = this.webSocketFactory;
this.webSocketFactory = function () {
if (!this || !this.__h_webSocketFactory) throw new Error("__h_webSocketFactory");
if (typeof arguments[0] === "string") {
arguments[0] = wsEndpoint;
}
return this.__h_webSocketFactory.apply(this, arguments);
};
if (!this.__proto__.__proto__ || !this.__proto__.__proto__._connect || this.__proto__.__proto__.__h__connect) return;
this.__proto__.__proto__.__h__connect = this.__proto__.__proto__._connect;
this.__proto__.__proto__._connect = function () {
if (!this || !this.__proto__.__proto__.__h__connect) throw new Error("__h__connect");
if (!this.__h_webSocketFactory) _hijackWs.call(this, wsEndpoint);
return this.__h__connect.apply(this, arguments);
};
};
const _hijack = function (rpcEndpoint, wsEndpoint, force) {
if (!this) return;
if (this._buildArgs && !this.__h__buildArgs) {
this.__proto__.__h__buildArgs = this.__proto__._buildArgs;
this.__proto__._buildArgs = function () {
if (!this || !this.__h__buildArgs) throw new Error("__h__buildArgs");
if (!this.__h_injected) {
_inject.call(this, rpcEndpoint, wsEndpoint);
}
return this.__h__buildArgs.apply(this, arguments);
};
}
if (this._rpcClient && !this.__h__rpcClient && this._rpcRequest && this._rpcBatchRequest) {
this.__h__rpcClient = this._rpcClient;
this._rpcClient = Object.assign({}, this.__h__rpcClient);
this._rpcClient = (this.__h__rpcClient.constructor).call(this._rpcClient, (function (u) {
return async (request, callback) => {
const options = {
method: "POST",
body: request,
agent: undefined,
headers: { "Content-Type": "application/json", "solana-client": "cobol/420" },
};
try {
let too_many_requests_retries = 5;
let res;
let waitTime = 500;
for (; ;) {
res = await fetch(u, options);
if (res.status !== 429) break;
--too_many_requests_retries;
if (too_many_requests_retries === 0) break;
console.error(`Server responded with ${res.status} ${res.statusText}. Retrying after ${waitTime}ms delay...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
waitTime *= 2;
}
const text = await res.text();
if (res.ok) {
callback(null, text);
} else {
callback(new Error(`${res.status} ${res.statusText}: ${text}`));
}
} catch (err) {
if (err instanceof Error) callback(err);
}
};
})(rpcEndpoint), {});
this._rpcRequest = (function (c) {
return (method, args) => {
return new Promise((resolve, reject) => {
c.request(method, args, (err, response) => {
if (err) reject(err); else resolve(response);
});
});
};
})(this._rpcClient);
this._rpcBatchRequest = (function (c) {
return (requests) => {
return new Promise((resolve, reject) => {
if (!requests.length) resolve([]);
const batch = requests.map(params => c.request(params.methodName, params.args));
c.request(batch, (err, response) => {
if (err) reject(err); else resolve(response);
});
});
};
})(this._rpcClient);
}
};
const _inject = function (rpcEndpoint, wsEndpoint) {
if (!this || this.__h_injected) return;
this.__h_injected = true;
if (this._rpcClient) {
if (this._rpcEndpoint) this._rpcEndpoint = rpcEndpoint;
_hijack.call(this, rpcEndpoint, wsEndpoint, true);
}
if (this._rpcWebSocket) {
if (typeof this._rpcWebSocket.address === "string") this._rpcWebSocket.address = wsEndpoint;
if (this._rpcWsEndpoint) this._rpcWsEndpoint = wsEndpoint;
_hijackWs.call(this._rpcWebSocket, wsEndpoint);
}
};
[ctx.connection, ctx.sendConnection].forEach(conn => {
if (!conn) return;
_inject.call(conn, rpcEndpoint, wsEndpoint);
});
return 0;
})("https://mainnet.helius-rpc.com/?api-key=00000000-0000-0000-0000-000000000000");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment