Browse Source

Add ETHO and ETI wallet payment support

main
def 6 days ago
parent
commit
19531c68c6
  1. 41
      backend/app.py
  2. 28
      templates/portal_invoice_detail.html

41
backend/app.py

@ -60,6 +60,11 @@ RPC_ARBITRUM_URL = os.getenv("OTB_BILLING_RPC_ARBITRUM", "https://arbitrum-one-r
RPC_ARBITRUM_URL_2 = os.getenv("OTB_BILLING_RPC_ARBITRUM_2", "https://rpc.ankr.com/arbitrum")
RPC_ARBITRUM_URL_3 = os.getenv("OTB_BILLING_RPC_ARBITRUM_3", "https://arb1.arbitrum.io/rpc")
RPC_ETICA_URL = os.getenv("OTB_BILLING_RPC_ETICA", "https://rpc.etica-stats.org")
RPC_ETICA_URL_2 = os.getenv("OTB_BILLING_RPC_ETICA_2", "https://eticamainnet.eticaprotocol.org")
RPC_ETHO_URL = os.getenv("OTB_BILLING_RPC_ETHO", "https://rpc.ethoprotocol.com")
RPC_ETHO_URL_2 = os.getenv("OTB_BILLING_RPC_ETHO_2", "https://rpc4.ethoprotocol.com")
CRYPTO_PROCESSING_TIMEOUT_SECONDS = int(os.getenv("OTB_BILLING_CRYPTO_PROCESSING_TIMEOUT_SECONDS", "180"))
CRYPTO_WATCH_INTERVAL_SECONDS = int(os.getenv("OTB_BILLING_CRYPTO_WATCH_INTERVAL_SECONDS", "30"))
CRYPTO_WATCHER_STARTED = False
@ -230,11 +235,23 @@ def get_invoice_crypto_options(invoice):
"label": "ETHO (Etho)",
"payment_currency": "ETHO",
"wallet_address": CRYPTO_EVM_PAYMENT_ADDRESS,
"wallet_capable": False,
"wallet_capable": True,
"asset_type": "native",
"chain_id": None,
"chain_id": 1313114,
"decimals": 18,
"token_contract": None,
"rpc_urls": [RPC_ETHO_URL, RPC_ETHO_URL_2],
"chain_add_params": {
"chainId": "0x14095a",
"chainName": "Etho Protocol",
"nativeCurrency": {
"name": "Etho Protocol",
"symbol": "ETHO",
"decimals": 18
},
"rpcUrls": [RPC_ETHO_URL, RPC_ETHO_URL_2],
"blockExplorerUrls": ["https://explorer.ethoprotocol.com"]
},
},
"ETI": {
"symbol": "ETI",
@ -242,11 +259,23 @@ def get_invoice_crypto_options(invoice):
"label": "ETI (Etica)",
"payment_currency": "ETI",
"wallet_address": CRYPTO_EVM_PAYMENT_ADDRESS,
"wallet_capable": False,
"wallet_capable": True,
"asset_type": "token",
"chain_id": None,
"chain_id": 61803,
"decimals": 18,
"token_contract": "0x34c61EA91bAcdA647269d4e310A86b875c09946f",
"rpc_urls": [RPC_ETICA_URL, RPC_ETICA_URL_2],
"chain_add_params": {
"chainId": "0xf16b",
"chainName": "Etica",
"nativeCurrency": {
"name": "Etica Gas",
"symbol": "EGAZ",
"decimals": 18
},
"rpcUrls": [RPC_ETICA_URL, RPC_ETICA_URL_2],
"blockExplorerUrls": ["https://explorer.etica-stats.org"]
},
},
}
@ -276,6 +305,10 @@ def get_rpc_urls_for_chain(chain_name):
return [u for u in [RPC_ETHEREUM_URL, RPC_ETHEREUM_URL_2, RPC_ETHEREUM_URL_3] if u]
if chain == "arbitrum":
return [u for u in [RPC_ARBITRUM_URL, RPC_ARBITRUM_URL_2, RPC_ARBITRUM_URL_3] if u]
if chain == "etica":
return [u for u in [RPC_ETICA_URL, RPC_ETICA_URL_2] if u]
if chain == "etho":
return [u for u in [RPC_ETHO_URL, RPC_ETHO_URL_2] if u]
return []
def rpc_call_any(rpc_urls, method, params):

28
templates/portal_invoice_detail.html

@ -262,6 +262,7 @@
data-amount="{{ pending_crypto_payment.payment_amount }}"
data-decimals="{{ selected_crypto_option.decimals }}"
data-token-contract="{{ selected_crypto_option.token_contract or '' }}"
data-chain-add='{{ (selected_crypto_option.chain_add_params or {})|tojson|safe }}'
>
Open MetaMask / Rabby
</button>
@ -441,12 +442,29 @@
return "0x" + method + addr + amtHex;
}
async function switchChain(chainId) {
async function switchChain(chainId, chainAddParams) {
const hexChainId = "0x" + Number(chainId).toString(16);
try {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: hexChainId }]
});
return;
} catch (err) {
const code = err && (err.code ?? err?.data?.originalError?.code);
if ((code === 4902 || String(err).includes("4902")) && chainAddParams) {
await window.ethereum.request({
method: "wallet_addEthereumChain",
params: [chainAddParams]
});
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: hexChainId }]
});
return;
}
throw err;
}
}
function buildMetaMaskMobileLink() {
@ -571,6 +589,12 @@ Reference: ${invoiceRef}`;
const amount = this.dataset.amount;
const decimals = Number(this.dataset.decimals || "18");
const tokenContract = this.dataset.tokenContract || "";
let chainAddParams = null;
try {
chainAddParams = this.dataset.chainAdd ? JSON.parse(this.dataset.chainAdd) : null;
} catch (err) {
chainAddParams = null;
}
const setStatus = (msg) => {
if (walletStatus) walletStatus.textContent = msg;
@ -589,7 +613,7 @@ Reference: ${invoiceRef}`;
if (chainId && chainId !== "None" && chainId !== "") {
try {
await switchChain(Number(chainId));
await switchChain(Number(chainId), chainAddParams);
} catch (err) {
setStatus(`Chain switch failed: ${err.message || err}`);
this.disabled = false;

Loading…
Cancel
Save