Skip to content

Commit

Permalink
Merge pull request #99 from secretkeylabs/chore/add-runes-etching-exa…
Browse files Browse the repository at this point in the history
…mple

etching example + cleanup
  • Loading branch information
m-aboelenein authored Apr 16, 2024
2 parents 97b5166 + 1a0c837 commit 5efa6b3
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 21 deletions.
2 changes: 1 addition & 1 deletion example/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion example/src/App.tsx
Original file line number Diff line number Diff line change
@@ -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() {
Expand Down Expand Up @@ -51,6 +58,7 @@ function App() {
<SendStx network={network} />
<SendBtc network={network} />
<MintRunes network={network} addresses={addressInfo} />
<EtchRunes network={network} addresses={addressInfo} />
</div>
</div>
);
Expand Down
171 changes: 171 additions & 0 deletions example/src/components/EtchRunes/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
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<number>();
const [totalSize, setTotalSize] = useState<number>();
const [fundTxId, setFundTxId] = useState<string>('');
const [runeName, setRuneName] = useState<string>('');
const [feeRate, setFeeRate] = useState<string>('');
const [symbol, setSymbol] = useState<string>('');
const [preMine, setPreMine] = useState<string>('');
const [divisibility, setDivisibility] = useState<string>('');
const [amount, setAmount] = useState<string>('');
const [mintCap, setMintCap] = useState<string>('');

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,
terms:
amount || mintCap
? {
amount: amount || undefined,
cap: mintCap || undefined,
}
: 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,
terms:
amount || mintCap
? {
amount: amount || undefined,
cap: mintCap || undefined,
}
: 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 (
<>
<div className="card">
<h3>Etch Runes</h3>
<div
style={{
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-between',
paddingRight: 100,
marginBottom: 20,
}}
>
<div>
<h4>Rune Name</h4>
<input type="text" value={runeName} onChange={(e) => setRuneName(e.target.value)} />
</div>
<div>
<h4>Symbol</h4>
<input type="text" value={symbol} onChange={(e) => setSymbol(e.target.value)} />
</div>
<div>
<h4>Divisibility</h4>
<input
type="number"
value={divisibility}
onChange={(e) => setDivisibility(e.target.value)}
/>
</div>
<div>
<h4>Premine</h4>
<input type="number" value={preMine} onChange={(e) => setPreMine(e.target.value)} />
</div>
<div>
<h4>Amount</h4>
<input type="number" value={amount} onChange={(e) => setAmount(e.target.value)} />
</div>
<div>
<h4>Mint Cap</h4>
<input type="number" value={mintCap} onChange={(e) => setMintCap(e.target.value)} />
</div>
<div>
<h4>feeRate (sats/vb)</h4>
<input type="number" value={feeRate} onChange={(e) => setFeeRate(e.target.value)} />
</div>
</div>

<button onClick={onClickEstimate} disabled={!runeName || !feeRate}>
Estimate Etch
</button>
</div>

{totalCost && (
<div className="card">
<div>
<h3>Rune Name</h3>
<p className="success">{runeName}</p>
</div>
<div>
<h3>Total Cost (sats) - Total Size</h3>
<p className="success">
{totalCost} - {totalSize}
</p>
</div>
<button onClick={onClickExecute}>Execute Etch</button>
{fundTxId && (
<div className="success">
Success! Click{' '}
<a href={fundTxLink} target="_blank" rel="noreferrer">
here
</a>{' '}
to see your transaction
</div>
)}
</div>
)}
</>
);
};

export default EtchRunes;
1 change: 1 addition & 0 deletions example/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"scripts": {
"test": "jest",
"build": "npm run clean && tsup src/index.ts --format esm --dts",
"dev:build": "tsup src/index.ts --format esm --dts --watch",
"dev:example": "cd example && npm start",
"clean": "rimraf dist",
"lint": "prettier --write .",
Expand All @@ -22,7 +23,7 @@
]
},
"dependencies": {
"@sats-connect/core": "0.0.5",
"@sats-connect/core": "0.0.6",
"@sats-connect/ui": "0.0.4",
"@sats-connect/make-default-provider-config": "0.0.1"
},
Expand Down
20 changes: 9 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,23 +25,21 @@ import { makeDefaultConfig } from '@sats-connect/make-default-provider-config';
loadSelector();

class Wallet {
private static providerId: string | undefined;
private providerId: string | undefined;

private static defaultAdapters: Record<string, new () => SatsConnectAdapter> = defaultAdapters;
private defaultAdapters: Record<string, new () => SatsConnectAdapter> = defaultAdapters;

private static createCustomConfig?: (providers: SupportedWallet[]) => Config;
private createCustomConfig?: (providers: SupportedWallet[]) => Config;

private static isProviderSet(): boolean {
private isProviderSet(): boolean {
return !!this.providerId;
}

public static setCreateCustomConfig(
createCustomConfig: (providers: SupportedWallet[]) => Config
) {
public setCreateCustomConfig(createCustomConfig: (providers: SupportedWallet[]) => Config) {
this.createCustomConfig = createCustomConfig;
}

public static async selectProvider() {
public async selectProvider() {
const providers = getSupportedWallets();

if (providers.length === 0) {
Expand All @@ -57,12 +55,12 @@ class Wallet {
this.providerId = nextProviderId;
}

public static async disconnect() {
public async disconnect() {
this.providerId = undefined;
removeDefaultProvider();
}

public static async request<Method extends keyof Requests>(
public async request<Method extends keyof Requests>(
method: Method,
params: Params<Method>
): Promise<RpcResult<Method>> {
Expand Down Expand Up @@ -114,4 +112,4 @@ class Wallet {

export * from '@sats-connect/core';

export default Wallet;
export default new Wallet();

0 comments on commit 5efa6b3

Please sign in to comment.