From 1c58e4ec303e52f36358035087b633cf13e7efd2 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Wed, 10 Dec 2025 14:57:52 -0300 Subject: [PATCH 1/8] feat: prop tokenId --- paybutton/src/index.tsx | 1 + react/lib/components/PayButton/PayButton.tsx | 8 +++-- .../PaymentDialog/PaymentDialog.tsx | 5 ++- react/lib/components/Widget/Widget.tsx | 3 ++ react/lib/util/chronik.ts | 34 +++++++++++++++---- react/lib/util/socket.ts | 11 ++++-- 6 files changed, 50 insertions(+), 12 deletions(-) diff --git a/paybutton/src/index.tsx b/paybutton/src/index.tsx index d6d911bc..56a056c7 100644 --- a/paybutton/src/index.tsx +++ b/paybutton/src/index.tsx @@ -106,6 +106,7 @@ const allowedProps = [ 'transactionText', 'size', 'donationRate', + 'tokenId' ]; const requiredProps = [ diff --git a/react/lib/components/PayButton/PayButton.tsx b/react/lib/components/PayButton/PayButton.tsx index f8c83981..be7684f8 100644 --- a/react/lib/components/PayButton/PayButton.tsx +++ b/react/lib/components/PayButton/PayButton.tsx @@ -59,6 +59,7 @@ export interface PayButtonProps extends ButtonProps { sizeScaleAlreadyApplied?: boolean; donationAddress?: string; donationRate?: number; + tokenId?: string; } export const PayButton = ({ @@ -92,7 +93,8 @@ export const PayButton = ({ size = 'md', sizeScaleAlreadyApplied = false, donationRate = DEFAULT_DONATION_RATE, - donationAddress = config.donationAddress + donationAddress = config.donationAddress, + tokenId, }: PayButtonProps): React.ReactElement => { const [dialogOpen, setDialogOpen] = useState(false); const [disabled, setDisabled] = useState(false); @@ -310,7 +312,8 @@ export const PayButton = ({ expectedPaymentId: paymentId, currencyObj, donationRate - } + }, + tokenId, }) } if (altpaymentSocket === undefined && useAltpayment) { @@ -466,6 +469,7 @@ export const PayButton = ({ donationRate={donationRate} convertedCurrencyObj={convertedCurrencyObj} setConvertedCurrencyObj={setConvertedCurrencyObj} + tokenId={tokenId} /> {errorMsg && (

{ const [success, setSuccess] = useState(false); const [internalDisabled, setInternalDisabled] = useState(false); @@ -259,6 +261,7 @@ export const PaymentDialog = ({ donationRate={donationRate} convertedCurrencyObj={convertedCurrencyObj} setConvertedCurrencyObj={setConvertedCurrencyObj} + tokenId={tokenId} foot={success && ( = props => { donationRate = DEFAULT_DONATION_RATE, setConvertedCurrencyObj = () => {}, setPaymentId, + tokenId, } = props; const [loading, setLoading] = useState(true); const [draftAmount, setDraftAmount] = useState("") @@ -541,6 +543,7 @@ export const Widget: React.FunctionComponent = props => { wsBaseUrl, setTxsSocket: setThisTxsSocket, setNewTxs: setThisNewTxs, + tokenId, }) if (thisUseAltpayment) { await setupAltpaymentSocket({ diff --git a/react/lib/util/chronik.ts b/react/lib/util/chronik.ts index 7714d257..205db3b0 100644 --- a/react/lib/util/chronik.ts +++ b/react/lib/util/chronik.ts @@ -113,6 +113,24 @@ export async function satoshisToUnit(satoshis: bigint, networkFormat: string): P throw new Error('[CHRONIK]: Invalid address') } +const getTokenAmount = async (transaction: Tx, tokenId: string, address: string, networkSlug: string): Promise => { + let totalTokenOutput = BigInt(0); + + for (const output of transaction.outputs) { + if (output.token?.tokenId === tokenId) { + const outputAddress = outputScriptToAddress(networkSlug, output.outputScript) + + if(outputAddress === address) { + const atoms = BigInt(output.token.atoms); + + totalTokenOutput += atoms / BigInt(100); + } + } + } + + return totalTokenOutput.toString(); +} + const getTransactionAmountAndData = async (transaction: Tx, addressString: string): Promise<{amount: string, opReturn: string}> => { let totalOutput = BigInt(0); let totalInput = BigInt(0); @@ -145,14 +163,15 @@ const getTransactionAmountAndData = async (transaction: Tx, addressString: stri } } -const getTransactionFromChronikTransaction = async (transaction: Tx, address: string): Promise => { +const getTransactionFromChronikTransaction = async (transaction: Tx, address: string, tokenId?: string): Promise => { const { amount, opReturn } = await getTransactionAmountAndData(transaction, address) const parsedOpReturn = resolveOpReturn(opReturn) const networkSlug = getAddressPrefix(address) const inputAddresses = getSortedInputAddresses(networkSlug, transaction) + const tokenAmount = tokenId ? await getTokenAmount(transaction, tokenId, address, networkSlug) : undefined; return { hash: transaction.txid, - amount, + amount: tokenId ? tokenAmount! : amount, address, timestamp: transaction.block !== undefined ? transaction.block.timestamp : transaction.timeFirstSeen, confirmed: transaction.block !== undefined, @@ -241,7 +260,8 @@ export const parseWebsocketMessage = async ( wsMsg: any, setNewTx: Function, chronik: ChronikClient, - address: string + address: string, + tokenId?: string ): Promise => { const { type } = wsMsg; if (type === 'Error') { @@ -252,7 +272,7 @@ export const parseWebsocketMessage = async ( case 'TX_ADDED_TO_MEMPOOL': { const rawTransaction = await chronik.tx(wsMsg.txid); - const transaction = await getTransactionFromChronikTransaction(rawTransaction, address ?? '') + const transaction = await getTransactionFromChronikTransaction(rawTransaction, address ?? '', tokenId) setNewTx([transaction]); break; @@ -264,7 +284,8 @@ export const parseWebsocketMessage = async ( export const initializeChronikWebsocket = async ( address: string, - setNewTx: Function + setNewTx: Function, + tokenId?: string ): Promise => { const networkSlug = getAddressPrefix(address) const blockchainUrls = config.networkBlockchainURLs[networkSlug]; @@ -279,7 +300,8 @@ export const initializeChronikWebsocket = async ( msg, setNewTx, chronik, - address + address, + tokenId ); }, }); diff --git a/react/lib/util/socket.ts b/react/lib/util/socket.ts index 2961ff3b..7ebf4886 100644 --- a/react/lib/util/socket.ts +++ b/react/lib/util/socket.ts @@ -122,6 +122,7 @@ interface SetupTxsSocketParams { setNewTxs: Function setDialogOpen?: Function checkSuccessInfo?: CheckSuccessInfo + tokenId?: string } export const setupTxsSocket = async (params: SetupTxsSocketParams): Promise => { @@ -145,9 +146,13 @@ export const setupChronikWebSocket = async (params: SetupTxsSocketParams): Promi params.setTxsSocket(undefined); } - const newChronikSocket = await initializeChronikWebsocket(params.address, (transactions: Transaction[]) => { - params.setNewTxs(transactions); - }); + const newChronikSocket = await initializeChronikWebsocket( + params.address, + (transactions: Transaction[]) => { + params.setNewTxs(transactions); + }, + params.tokenId + ); params.setTxsSocket(newChronikSocket); } From 46547a443233dffe8924300a75353c65746d68e4 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Thu, 11 Dec 2025 13:30:36 -0300 Subject: [PATCH 2/8] feat: token icon --- react/lib/components/Widget/Widget.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index 96b3efad..3e467a3e 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -502,6 +502,10 @@ export const Widget: React.FunctionComponent = props => { )}' stroke='%23fff' stroke-width='.6'/%3E%3Cpath d='m7.2979 14.697-2.6964-2.6966 0.89292-0.8934c0.49111-0.49137 0.90364-0.88958 0.91675-0.88491 0.013104 0.0047 0.71923 0.69866 1.5692 1.5422 0.84994 0.84354 1.6548 1.6397 1.7886 1.7692l0.24322 0.23547 7.5834-7.5832 1.8033 1.8033-9.4045 9.4045z' fill='%23fff' stroke-width='.033708'/%3E%3C/svg%3E%0A` }, [theme]) + const getTokenIconUrl = useCallback((tokenId: string): string => { + return `https://icons.etokens.cash/128/${tokenId}.png` + }, []) + useEffect(() => { if (thisCurrencyObject?.string !== undefined) { const raw = stripFormatting(thisCurrencyObject.string); @@ -1036,6 +1040,7 @@ export const Widget: React.FunctionComponent = props => { } } + const qrCode = ( = props => { bgColor={isDarkMode ? '#1a1a1a' : '#ffffff'} fgColor={theme.palette.tertiary as unknown as string} imageSettings={{ - src: success ? checkSvg : isValidCashAddress(to) ? bchSvg : xecSvg, + src: success ? checkSvg : tokenId ? getTokenIconUrl(tokenId) : isValidCashAddress(to) ? bchSvg : xecSvg, excavate: false, height: 112, width: 112, From 8fa548734cbae877334166108068b487a9c5810e Mon Sep 17 00:00:00 2001 From: lissavxo Date: Tue, 23 Dec 2025 02:30:23 -0300 Subject: [PATCH 3/8] feat: adjust url add token params --- react/lib/components/Widget/Widget.tsx | 49 ++++++++++++++++++++------ react/lib/util/chronik.ts | 13 ++++++- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index 3e467a3e..a1fea0e1 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -54,6 +54,7 @@ import { MINIMUM_ALTPAYMENT_CAD_AMOUNT, } from '../../altpayment' +import { getTokenInfo } from '../../util/chronik' export interface WidgetProps { to: string @@ -333,6 +334,7 @@ export const Widget: React.FunctionComponent = props => { const [thisAmount, setThisAmount] = useState(props.amount) const [thisCurrencyObject, setThisCurrencyObject] = useState(props.currencyObject) + const [tokenName, setTokenName] = useState(null) const blurCSS = isPropsTrue(disabled) ? { filter: 'blur(5px)' } : {} // inject keyframes once (replacement for @global in makeStyles) @@ -596,6 +598,19 @@ export const Widget: React.FunctionComponent = props => { })() }, [thisNewTxs, to, apiBaseUrl]) + useEffect(() => { + ;(async (): Promise => { + if (tokenId && tokenId !== null && tokenId !== '' ) { + const tokenInfo = await getTokenInfo(tokenId, to) + const name = tokenInfo.genesisInfo.tokenTicker ?? null + setTokenName(name) + + return + } + setLoading(false) + })() + }, [tokenId, to]) + useEffect(() => { if ( isChild || @@ -812,7 +827,7 @@ export const Widget: React.FunctionComponent = props => { setText( `Send ${amountToDisplay} ${thisCurrencyObject.currency} = ${convertedAmountToDisplay} ${thisAddressType}`, ) - const url = resolveUrl(thisAddressType, convertedObj.float) + const url = resolveUrl(thisAddressType, convertedObj.float, tokenId) setUrl(url ?? "") } } else { @@ -837,16 +852,16 @@ export const Widget: React.FunctionComponent = props => { amountToDisplay = amountWithDonationObj.string } - setText(`Send ${amountToDisplay} ${cur}`) + setText(`Send ${amountToDisplay} ${tokenId ? tokenName : cur}`) // Pass base amount (without donation) to resolveUrl - nextUrl = resolveUrl(cur, baseAmount) + nextUrl = resolveUrl(cur, baseAmount, tokenId) } else { - setText(`Send any amount of ${thisAddressType}`) - nextUrl = resolveUrl(thisAddressType) + setText(`Send any amount of ${tokenId ? tokenName : thisAddressType}`) + nextUrl = resolveUrl(thisAddressType, undefined, tokenId) } setUrl(nextUrl ?? '') } - }, [to, thisCurrencyObject, price, thisAmount, opReturn, hasPrice, isCashtabAvailable, userDonationRate, donationEnabled, disabled, donationAddress, currency, randomSatoshis, thisAddressType, shouldApplyDonation]) + }, [to, thisCurrencyObject, price, thisAmount, opReturn, hasPrice, isCashtabAvailable, userDonationRate, donationEnabled, disabled, donationAddress, currency, randomSatoshis, thisAddressType, shouldApplyDonation, tokenName, tokenId]) useEffect(() => { try { @@ -968,7 +983,7 @@ export const Widget: React.FunctionComponent = props => { setRecentlyCopied(true) }, [disabled, to, url, setCopied, setRecentlyCopied, qrLoading]) - const resolveUrl = useCallback((currency: string, amount?: number) => { + const resolveUrl = useCallback((currency: string, amount?: number, tokenId?: string) => { if (disabled || !to) return; const prefix = CURRENCY_PREFIXES_MAP[currency.toLowerCase() as typeof CRYPTO_CURRENCIES[number]]; @@ -985,11 +1000,18 @@ export const Widget: React.FunctionComponent = props => { const donationPercent = userDonationRate / 100 // Calculate donation amount from base amount const thisDonationAmount = amount * donationPercent - - thisUrl += `?amount=${amount}` - thisUrl += `&addr=${donationAddress}&amount=${thisDonationAmount.toFixed(decimals)}`; + if (tokenId) { + thisUrl += `?token_decimalized_qty=${amount}` + } else { + thisUrl += `?amount=${amount}` + thisUrl += `&addr=${donationAddress}&amount=${thisDonationAmount.toFixed(decimals)}`; + } } else { - thisUrl += `?amount=${amount}` + if (tokenId) { + thisUrl += `?token_decimalized_qty=${amount}` + } else { + thisUrl += `?amount=${amount}` + } } } @@ -998,6 +1020,11 @@ export const Widget: React.FunctionComponent = props => { thisUrl += `${separator}op_return_raw=${opReturn}`; } + if (tokenId) { + const separator = thisUrl.includes('?') ? '&' : '?'; + thisUrl += `${separator}token_id=${tokenId}`; + } + return thisUrl; }, [disabled, to, opReturn, userDonationRate, donationAddress, donationEnabled, shouldApplyDonation] diff --git a/react/lib/util/chronik.ts b/react/lib/util/chronik.ts index 205db3b0..32835037 100644 --- a/react/lib/util/chronik.ts +++ b/react/lib/util/chronik.ts @@ -255,6 +255,18 @@ function getSortedInputAddresses (networkSlug: string, transaction: Tx): string[ return sortedInputAddresses } +export const getTokenInfo = async (tokenId: string, address:string) => { + const networkSlug = getAddressPrefix(address) + const blockchainUrls = config.networkBlockchainURLs[networkSlug]; + + const chronik = await ChronikClient.useStrategy( + ConnectionStrategy.AsOrdered, + blockchainUrls, + ); + const tokenInfo = await chronik.token(tokenId); + + return tokenInfo; +} export const parseWebsocketMessage = async ( wsMsg: any, @@ -273,7 +285,6 @@ export const parseWebsocketMessage = async ( const rawTransaction = await chronik.tx(wsMsg.txid); const transaction = await getTransactionFromChronikTransaction(rawTransaction, address ?? '', tokenId) - setNewTx([transaction]); break; } From 3a01eb26737cf3a5ead4b8427607a142aca9e081 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Sat, 27 Dec 2025 16:17:05 -0300 Subject: [PATCH 4/8] docs: token id --- docs/README.md | 29 +++++++++++++++++++++++++++++ docs/_sidebar.md | 2 ++ docs/zh-cn/README.md | 30 ++++++++++++++++++++++++++++++ docs/zh-cn/_sidebar.md | 2 ++ docs/zh-tw/README.md | 31 +++++++++++++++++++++++++++++++ docs/zh-tw/_sidebar.md | 3 +++ 6 files changed, 97 insertions(+) diff --git a/docs/README.md b/docs/README.md index e0cf1965..367cbdad 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1127,6 +1127,35 @@ donationRate = 10 ``` +## token-id + +> **The ‘tokenId’ parameter defines the eToken that will be used in the button or widget.** + +?> The token ID parameter is optional.It accepts a string containing the token ID. Default value is null. + + +**Example:** + + +#### ** HTML ** + +```html +token-id="c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + +#### ** JavaScript ** + +```javascript +tokenId: "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + +#### ** React ** + +```react +tokenId = "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + + # Contribute PayButton is a community-driven open-source initiative. Contributions from the community are _crucial_ to the success of the project. diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 940e9fdb..814af78b 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -34,6 +34,8 @@ - [disable-sound](/?id=disable-sound) - [size](/?id=size) - [donation-rate](/?id=donation-rate) + - [token-id](/?id=token-id) + - [Contribute](/?id=contribute) - [Developer Quick Start](/?id=developer-quick-start) diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md index 2e5addaa..ce1d5177 100644 --- a/docs/zh-cn/README.md +++ b/docs/zh-cn/README.md @@ -1126,6 +1126,36 @@ donationRate = 10 ``` +## token-id + +> **「tokenId」 参数用于定义在按钮或小组件中使用的 eToken。** + +?> tokenId 参数是可选的。它接受一个包含 token ID 的字符串。默认值为 null。 + + +**Example:** + + +#### ** HTML ** + +```html +token-id="c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + +#### ** JavaScript ** + +```javascript +tokenId: "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + +#### ** React ** + +```react +tokenId = "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + + + # 贡献 diff --git a/docs/zh-cn/_sidebar.md b/docs/zh-cn/_sidebar.md index 6acc45ce..12556353 100644 --- a/docs/zh-cn/_sidebar.md +++ b/docs/zh-cn/_sidebar.md @@ -33,6 +33,8 @@ - [disable-sound](/zh-cn/?id=disable-sound) - [size](/zh-cn/?id=size) - [donation-rate](/zh-cn/?id=donation-rate) + - [token-id](/zh-cn/?id=token-id) + - [贡献](/zh-cn/?id=贡献) - [开发人员快速入门](/zh-cn/?id=开发人员快速入门) - [入门](/zh-cn/?id=入门) diff --git a/docs/zh-tw/README.md b/docs/zh-tw/README.md index c93271f1..d9a7e118 100644 --- a/docs/zh-tw/README.md +++ b/docs/zh-tw/README.md @@ -1122,6 +1122,37 @@ donationRate = 10 ``` +## token-id + +> **「tokenId」 參數用於定義在按鈕或小工具中使用的 eToken。** + +?> tokenId 參數為選填。它接受一個包含 token ID 的字串。預設值為 null。 + + +**Example:** + + +#### ** HTML ** + +```html +token-id="c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + +#### ** JavaScript ** + +```javascript +tokenId: "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + +#### ** React ** + +```react +tokenId = "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" +``` + + + + # 貢獻 diff --git a/docs/zh-tw/_sidebar.md b/docs/zh-tw/_sidebar.md index 8bda09ed..39ceda84 100644 --- a/docs/zh-tw/_sidebar.md +++ b/docs/zh-tw/_sidebar.md @@ -32,6 +32,9 @@ - [auto-close](/zh-tw/?id=auto-close) - [disable-sound](/zh-tw/?id=disable-sound) - [size](/zh-tw/?id=size) + - [donation-rate](/zh-tw/?id=donation-rate) + - [token-id](/zh-tw/?id=token-id) + - [貢獻](/zh-tw/?id=貢獻) - [開發人員快速入門](/zh-tw/?id=開發人員快速入門) - [入門](/zh-tw/?id=入門) From 76d0bfcc4feea3d83a080be159567983c7f1ed44 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Sat, 27 Dec 2025 20:13:37 -0300 Subject: [PATCH 5/8] fix: token decimals --- react/lib/components/Widget/Widget.tsx | 2 +- react/lib/util/chronik.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index a1fea0e1..30c12f0a 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -600,7 +600,7 @@ export const Widget: React.FunctionComponent = props => { useEffect(() => { ;(async (): Promise => { - if (tokenId && tokenId !== null && tokenId !== '' ) { + if (tokenId && tokenId !== '' ) { const tokenInfo = await getTokenInfo(tokenId, to) const name = tokenInfo.genesisInfo.tokenTicker ?? null setTokenName(name) diff --git a/react/lib/util/chronik.ts b/react/lib/util/chronik.ts index 32835037..8ae51662 100644 --- a/react/lib/util/chronik.ts +++ b/react/lib/util/chronik.ts @@ -115,6 +115,9 @@ export async function satoshisToUnit(satoshis: bigint, networkFormat: string): P const getTokenAmount = async (transaction: Tx, tokenId: string, address: string, networkSlug: string): Promise => { let totalTokenOutput = BigInt(0); + const tokenInfo = await getTokenInfo(tokenId, address); + const decimals = tokenInfo.genesisInfo.decimals; + const divisor = 10 ** decimals; for (const output of transaction.outputs) { if (output.token?.tokenId === tokenId) { @@ -123,7 +126,7 @@ const getTokenAmount = async (transaction: Tx, tokenId: string, address: string, if(outputAddress === address) { const atoms = BigInt(output.token.atoms); - totalTokenOutput += atoms / BigInt(100); + totalTokenOutput += atoms / BigInt(divisor); } } } From ea30d507446b2993a31951ea6578a131932376c4 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Sat, 27 Dec 2025 20:16:11 -0300 Subject: [PATCH 6/8] refactor: error handling token info --- react/lib/components/Widget/Widget.tsx | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index 30c12f0a..1bc61809 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -600,11 +600,18 @@ export const Widget: React.FunctionComponent = props => { useEffect(() => { ;(async (): Promise => { - if (tokenId && tokenId !== '' ) { - const tokenInfo = await getTokenInfo(tokenId, to) - const name = tokenInfo.genesisInfo.tokenTicker ?? null - setTokenName(name) - + if (tokenId && tokenId !== '') { + try { + const tokenInfo = await getTokenInfo(tokenId, to) + const name = tokenInfo.genesisInfo.tokenTicker ?? null + setTokenName(name) + } catch (err) { + console.error('Failed to fetch token info:', err) + setTokenName(null) + setErrorMsg('Unable to load token information') + } finally { + setLoading(false) + } return } setLoading(false) From 6348b48b1001099c69e816881a62107d3b9921d1 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Sat, 27 Dec 2025 20:19:49 -0300 Subject: [PATCH 7/8] docs: fix markdown --- docs/README.md | 8 ++++---- docs/zh-cn/README.md | 6 +++--- docs/zh-tw/README.md | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/README.md b/docs/README.md index 367cbdad..c1668bd3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1131,25 +1131,25 @@ donationRate = 10 > **The ‘tokenId’ parameter defines the eToken that will be used in the button or widget.** -?> The token ID parameter is optional.It accepts a string containing the token ID. Default value is null. +?> The token ID parameter is optional. It accepts a string containing the token ID. Default value is null. **Example:** -#### ** HTML ** +#### **HTML** ```html token-id="c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" ``` -#### ** JavaScript ** +#### **JavaScript** ```javascript tokenId: "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" ``` -#### ** React ** +#### **React** ```react tokenId = "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md index ce1d5177..fedca865 100644 --- a/docs/zh-cn/README.md +++ b/docs/zh-cn/README.md @@ -1136,19 +1136,19 @@ donationRate = 10 **Example:** -#### ** HTML ** +#### **HTML** ```html token-id="c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" ``` -#### ** JavaScript ** +#### **JavaScript** ```javascript tokenId: "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" ``` -#### ** React ** +#### **React** ```react tokenId = "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" diff --git a/docs/zh-tw/README.md b/docs/zh-tw/README.md index d9a7e118..e65e4af5 100644 --- a/docs/zh-tw/README.md +++ b/docs/zh-tw/README.md @@ -1132,19 +1132,19 @@ donationRate = 10 **Example:** -#### ** HTML ** +#### **HTML** ```html token-id="c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" ``` -#### ** JavaScript ** +#### **JavaScript** ```javascript tokenId: "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" ``` -#### ** React ** +#### **React** ```react tokenId = "c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4" From 7dc35534f1fdddfb05fbaeaf9358b3b2ca032c64 Mon Sep 17 00:00:00 2001 From: lissavxo Date: Sat, 27 Dec 2025 20:34:56 -0300 Subject: [PATCH 8/8] refactor: add tokenId dependency --- react/lib/components/Widget/Widget.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/lib/components/Widget/Widget.tsx b/react/lib/components/Widget/Widget.tsx index 1bc61809..58591d63 100644 --- a/react/lib/components/Widget/Widget.tsx +++ b/react/lib/components/Widget/Widget.tsx @@ -1034,7 +1034,7 @@ export const Widget: React.FunctionComponent = props => { return thisUrl; }, - [disabled, to, opReturn, userDonationRate, donationAddress, donationEnabled, shouldApplyDonation] + [disabled, to, opReturn, userDonationRate, donationAddress, donationEnabled, shouldApplyDonation, tokenId] ) const stripFormatting = (s: string) => { return s.replace(/,/g, '').replace(/(\.\d*?[1-9])0+$/, '$1').replace(/\.0+$/, '');