94 lines
3.2 KiB
JavaScript
94 lines
3.2 KiB
JavaScript
const PAGE_REQUEST = 'shine-wallet-page-request';
|
|
const PAGE_RESPONSE = 'shine-wallet-page-response';
|
|
const PAGE_MESSAGE_TARGET_ORIGIN = '*';
|
|
|
|
function injectProviderBridge() {
|
|
const root = document.head || document.documentElement;
|
|
if (!root) return;
|
|
const script = document.createElement('script');
|
|
script.type = 'module';
|
|
script.src = chrome.runtime.getURL('provider-bridge.js');
|
|
script.dataset.shineWalletProvider = '1';
|
|
root.appendChild(script);
|
|
script.remove();
|
|
}
|
|
|
|
function respondToPage(id, ok, result, error, code) {
|
|
window.postMessage({
|
|
target: PAGE_RESPONSE,
|
|
id: String(id || ''),
|
|
ok: !!ok,
|
|
result: result || null,
|
|
error: error ? String(error) : '',
|
|
code: code ? String(code) : '',
|
|
}, PAGE_MESSAGE_TARGET_ORIGIN);
|
|
}
|
|
|
|
function sendRuntimeMessage(type, payload = {}) {
|
|
return new Promise((resolve, reject) => {
|
|
chrome.runtime.sendMessage({ type, payload }, (response) => {
|
|
if (chrome.runtime.lastError) {
|
|
const raw = String(chrome.runtime.lastError.message || 'Runtime message failed');
|
|
if (/Extension context invalidated/i.test(raw)) {
|
|
const error = new Error('Расширение было перезагружено или отключено. Обновите страницу и откройте кошелёк заново.');
|
|
error.code = 'EXTENSION_CONTEXT_INVALIDATED';
|
|
reject(error);
|
|
return;
|
|
}
|
|
reject(new Error(raw));
|
|
return;
|
|
}
|
|
if (!response?.ok) {
|
|
const error = new Error(String(response?.error || 'Wallet operation failed'));
|
|
error.code = String(response?.code || '');
|
|
reject(error);
|
|
return;
|
|
}
|
|
resolve(response);
|
|
});
|
|
});
|
|
}
|
|
|
|
window.addEventListener('message', (event) => {
|
|
if (event.source !== window) return;
|
|
const data = event.data || {};
|
|
if (data?.target !== PAGE_REQUEST) return;
|
|
|
|
const id = String(data?.id || '');
|
|
const method = String(data?.method || '');
|
|
const params = data?.params || {};
|
|
const origin = window.location.origin;
|
|
|
|
(async () => {
|
|
if (method === 'connect') {
|
|
const response = await sendRuntimeMessage('wallet:siteConnect', {
|
|
origin,
|
|
onlyIfTrusted: !!params?.onlyIfTrusted,
|
|
});
|
|
respondToPage(id, true, response.result || null);
|
|
return;
|
|
}
|
|
if (method === 'disconnect') {
|
|
const response = await sendRuntimeMessage('wallet:siteDisconnect', { origin });
|
|
respondToPage(id, true, response.result || null);
|
|
return;
|
|
}
|
|
if (method === 'signTransaction') {
|
|
const response = await sendRuntimeMessage('wallet:siteSignTransaction', {
|
|
origin,
|
|
publicKeyBase58: String(params?.publicKeyBase58 || '').trim(),
|
|
transactionBase64: String(params?.transactionBase64 || '').trim(),
|
|
comment: String(params?.comment || '').trim(),
|
|
transactionSummary: params?.transactionSummary || null,
|
|
});
|
|
respondToPage(id, true, response.result || null);
|
|
return;
|
|
}
|
|
respondToPage(id, false, null, 'Unsupported provider method', 'UNSUPPORTED_METHOD');
|
|
})().catch((error) => {
|
|
respondToPage(id, false, null, error?.message || 'Wallet bridge error', error?.code || '');
|
|
});
|
|
});
|
|
|
|
injectProviderBridge();
|