diff --git a/example/src/App.tsx b/example/src/App.tsx index 2a9807c..0daa8b5 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -1,6 +1,13 @@ import Wallet, { Address, BitcoinNetworkType, AddressPurpose } from 'sats-connect'; import './App.css'; -import { AddressDisplay, NetworkSelector, SendBtc, SendStx, MintRunes } from './components'; +import { + AddressDisplay, + NetworkSelector, + SendBtc, + SendStx, + MintRunes, + EtchRunes, +} from './components'; import { useLocalStorage } from './hooks'; function App() { @@ -51,6 +58,7 @@ function App() { + ); diff --git a/example/src/components/EtchRunes/index.tsx b/example/src/components/EtchRunes/index.tsx new file mode 100644 index 0000000..e9a01bd --- /dev/null +++ b/example/src/components/EtchRunes/index.tsx @@ -0,0 +1,147 @@ +import { useMemo, useState } from 'react'; +import Wallet, { Address, AddressPurpose, BitcoinNetworkType } from 'sats-connect'; + +type Props = { + network: BitcoinNetworkType; + addresses: Address[]; +}; + +const EtchRunes = ({ addresses, network }: Props) => { + const [totalCost, setTotalCost] = useState(); + const [totalSize, setTotalSize] = useState(); + const [fundTxId, setFundTxId] = useState(''); + const [runeName, setRuneName] = useState(''); + const [feeRate, setFeeRate] = useState(''); + const [symbol, setSymbol] = useState(''); + const [preMine, setPreMine] = useState(''); + const [divisibility, setDivisibility] = useState(''); + + const ordinalsAddress = useMemo( + () => addresses.find((a) => a.purpose === AddressPurpose.Ordinals)?.address || '', + [addresses] + ); + + const paymentAddress = useMemo( + () => addresses.find((a) => a.purpose === AddressPurpose.Payment)?.address || '', + [addresses] + ); + + const onClickEstimate = async () => { + const response = await Wallet.request('runes_estimateEtch', { + destinationAddress: ordinalsAddress, + feeRate: +feeRate, + symbol: symbol || undefined, + premine: preMine || undefined, + divisibility: +divisibility || undefined, + isMintable: true, + runeName: runeName, + network: network, + }); + + if (response.status === 'success') { + setTotalCost(response.result.totalCost); + setTotalSize(response.result.totalSize); + } else { + console.error(response.error); + alert('Error Fetching Estimate. See console for details.'); + } + }; + + const onClickExecute = async () => { + const response = await Wallet.request('runes_etch', { + destinationAddress: ordinalsAddress, + symbol: symbol || undefined, + premine: preMine || undefined, + feeRate: +feeRate, + isMintable: true, + runeName, + refundAddress: paymentAddress, + network, + }); + + if (response.status === 'success') { + setFundTxId(response.result.fundTransactionId); + } else { + console.error(response.error); + alert('Error sending BTC. See console for details.'); + } + }; + + const fundTxLink = + network === BitcoinNetworkType.Mainnet + ? `https://mempool.space/tx/${fundTxId}` + : `https://mempool.space/testnet/tx/${fundTxId}`; + + return ( + <> +
+

Etch Runes

+
+
+

Rune Name

+ setRuneName(e.target.value)} /> +
+
+

Symbol

+ setSymbol(e.target.value)} /> +
+
+

Divisibility

+ setDivisibility(e.target.value)} + /> +
+
+

Premine

+ setPreMine(e.target.value)} /> +
+
+

feeRate (sats/vb)

+ setFeeRate(e.target.value)} /> +
+
+ + +
+ + {totalCost && ( +
+
+

Rune Name

+

{runeName}

+
+
+

Total Cost (sats) - Total Size

+

+ {totalCost} - {totalSize} +

+
+ + {fundTxId && ( +
+ Success! Click{' '} + + here + {' '} + to see your transaction +
+ )} +
+ )} + + ); +}; + +export default EtchRunes; diff --git a/example/src/components/index.ts b/example/src/components/index.ts index f6ea304..1debe0a 100644 --- a/example/src/components/index.ts +++ b/example/src/components/index.ts @@ -3,3 +3,4 @@ export { default as NetworkSelector } from './NetworkSelector'; export { default as SendBtc } from './SendBtc'; export { default as SendStx } from './SendStx'; export { default as MintRunes } from './MintRunes'; +export { default as EtchRunes } from './EtchRunes';