Skip to content

Commit

Permalink
Add LaserEyesLogo component and integrate network support for CMDRUID
Browse files Browse the repository at this point in the history
  • Loading branch information
hathbanger committed Nov 14, 2024
1 parent 4ad6660 commit da03b64
Show file tree
Hide file tree
Showing 9 changed files with 550 additions and 30 deletions.
7 changes: 6 additions & 1 deletion apps/demo.lasereyes.build/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
SIGNET,
SUPPORTED_WALLETS,
TESTNET,
LaserEyesLogo,
TESTNET4,
useLaserEyes,
WalletIcon,
Expand Down Expand Up @@ -146,7 +147,7 @@ const App = ({ setNetwork }: { setNetwork: (n: NetworkType) => void }) => {
<ImNewTab />
</Link>
</div>
<div className={'border border-[#3c393f] w-full text-xl grow pb-8'}>
<div className={'border border-[#3c393f] w-full text-xl grow '}>
<div className={'flex flex-row items-center gap-4 '}>
<div className={'grow'} />
<div
Expand Down Expand Up @@ -410,6 +411,10 @@ const App = ({ setNetwork }: { setNetwork: (n: NetworkType) => void }) => {
</div>
</div>
</div>
<div className={'flex flex-row items-center gap-4 '}>
<LaserEyesLogo className={'m-4'} width={48} />
<div className={'grow'} />
</div>
</div>
<div className={'flex flex-wrap justify-center gap-8'}>
{Object.values(SUPPORTED_WALLETS).map(
Expand Down
5 changes: 2 additions & 3 deletions apps/demo.lasereyes.build/components/WalletCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,6 @@ const WalletCard = ({
//@ts-ignore
setSignedPsbt(signPsbtResponse)

console.log(signPsbtResponse)

if (
typeof signPsbtResponse.signedPsbtHex === 'string' &&
!signPsbtResponse.txId
Expand Down Expand Up @@ -382,7 +380,8 @@ const WalletCard = ({
try {
const inscriptionTxId = await inscribe(
Buffer.from(inscriptionText).toString('base64'),
'text/plain'
'text/plain',
network
)
toast.success(
<span className={'flex flex-col gap-1 items-center justify-center'}>
Expand Down
1 change: 1 addition & 0 deletions packages/lasereyes-core/src/client/providers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export abstract class WalletProvider {
paymentAddress: this.$store.get().paymentAddress,
paymentPublicKey: this.$store.get().paymentPublicKey,
signPsbt: this.signPsbt.bind(this),
network: this.$network.get(),
})
}
}
1 change: 0 additions & 1 deletion packages/lasereyes-core/src/client/providers/unisat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ export default class UnisatProvider extends WalletProvider {
if (!unisatAccounts) throw new Error('No accounts found')
await this.getNetwork().then((network) => {
if (this.network !== network) {
console.log('Network changed')
this.switchNetwork(this.network)
}
})
Expand Down
15 changes: 15 additions & 0 deletions packages/lasereyes-core/src/constants/networks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ export const ORANGE_TESTNET = 'Testnet'

export const LEATHER_MAINNET = 'mainnet'
export const LEATHER_TESTNET = 'testnet'

export const CMDRUID_MAINNET = 'main'
export const CMDRUID_TESTNET = 'testnet'
export const CMDRUID_SIGNET = 'signet'

export const MAINNET = 'mainnet'
export const SIGNET = 'signet'
export const TESTNET = 'testnet'
Expand Down Expand Up @@ -82,6 +87,16 @@ export const getOrangeNetwork = (network: string): BitcoinNetworkType => {
return ORANGE_MAINNET as BitcoinNetworkType
}

export const getCmDruidNetwork = (network: string) => {
if (network === MAINNET) return CMDRUID_MAINNET
if (network === TESTNET4) return CMDRUID_TESTNET
if (network === TESTNET) return CMDRUID_TESTNET
if (network === SIGNET) return CMDRUID_SIGNET
if (network === FRACTAL_MAINNET) return CMDRUID_MAINNET
if (network === FRACTAL_TESTNET) return CMDRUID_MAINNET
return CMDRUID_MAINNET
}

export const getNetworkForUnisat = (network: string) => {
if (network === UNISAT_MAINNET) return MAINNET
if (network === UNISAT_TESTNET) return TESTNET
Expand Down
75 changes: 50 additions & 25 deletions packages/lasereyes-core/src/lib/inscribe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import {
calculateValueOfUtxosGathered,
getAddressType,
getAddressUtxos,
getBitcoinNetwork,
getRedeemScript,
} from './helpers'
import { MAINNET, P2SH, P2TR } from '../constants'
import { getCmDruidNetwork, MAINNET, P2SH, P2TR } from '../constants'
import axios from 'axios'
import { getMempoolSpaceUrl } from './urls'
import * as bip39 from 'bip39'
Expand All @@ -36,6 +37,7 @@ export const inscribeContent = async ({
paymentAddress,
paymentPublicKey,
signPsbt,
network = MAINNET,
}: {
contentBase64?: string
mimeType?: ContentType
Expand All @@ -49,7 +51,8 @@ export const inscribeContent = async ({
psbtHex: string,
psbtBase64: string,
finalize?: boolean,
broadcast?: boolean
broadcast?: boolean,
network?: NetworkType
) => Promise<
| {
signedPsbtHex: string | undefined
Expand All @@ -58,12 +61,13 @@ export const inscribeContent = async ({
}
| undefined
>
network: NetworkType
}) => {
try {
if (!contentBase64 && !inscriptions) {
throw new Error('contentBase64 or inscriptions is required')
}
const privKeyBuff = await generatePrivateKey()
const privKeyBuff = await generatePrivateKey(network)
const privKey = Buffer.from(privKeyBuff!).toString('hex')
const ixs = inscriptions
? inscriptions
Expand All @@ -72,13 +76,12 @@ export const inscribeContent = async ({
mimeType,
})

console.log('INSCRIPTIONS', ixs)

const commitTx = await getCommitTx({
inscriptions: ixs,
paymentAddress,
paymentPublicKey,
privKey,
network,
})

if (!commitTx || !commitTx?.psbtHex) {
Expand All @@ -92,18 +95,20 @@ export const inscribeContent = async ({
commitTxHex,
commitTxBase64,
true,
false
false,
network
)
if (!response) throw new Error('sign psbt failed')
const psbt = bitcoin.Psbt.fromHex(response?.signedPsbtHex || '')
const extracted = psbt.extractTransaction()
const commitTxId = await broadcastTx(extracted.toHex(), MAINNET)
const commitTxId = await broadcastTx(extracted.toHex(), network)
if (!commitTxId) throw new Error('commit tx failed')
return await executeReveal({
inscriptions: ixs,
ordinalAddress,
privKey,
commitTxId,
network,
})
} catch (e) {
throw e
Expand All @@ -115,11 +120,13 @@ export const getCommitTx = async ({
paymentAddress,
paymentPublicKey,
privKey,
network,
}: {
inscriptions: { content: string; mimeType: ContentType }[]
paymentAddress: string
paymentPublicKey?: string
privKey: string
network: NetworkType
isDry?: boolean
}): Promise<
| {
Expand All @@ -137,15 +144,16 @@ export const getCommitTx = async ({
if (contentSize > 390000)
throw new Error('Content size is too large, must be less than 390kb')

const { fastestFee } = await getRecommendedFees(MAINNET)
const { fastestFee } = await getRecommendedFees(network)
const pubKey = ecc.keys.get_pubkey(String(privKey), true)
const psbt = new bitcoin.Psbt({
network: bitcoin.networks.bitcoin,
network: getBitcoinNetwork(network),
})

const { inscriberAddress } = createRevealAddressAndKeys(
pubKey,
inscriptions
inscriptions,
network
)

const estimatedSize = 5 * 34 * quantity
Expand All @@ -155,7 +163,7 @@ export const getCommitTx = async ({
const inscribeFees = Math.floor(commitSatsNeeded + revealSatsNeeded)
const utxosGathered: MempoolUtxo[] = await getAddressUtxos(
paymentAddress,
MAINNET
network
)
const filteredUtxos = utxosGathered
.filter((utxo: MempoolUtxo) => utxo.value > 3000)
Expand All @@ -171,10 +179,13 @@ export const getCommitTx = async ({
}

let accSats = 0
const addressScript = await bitcoin.address.toOutputScript(paymentAddress)
const addressScript = await bitcoin.address.toOutputScript(
paymentAddress,
getBitcoinNetwork(network)
)
let counter = 0
for await (const utxo of filteredUtxos) {
const paymentAddressType = getAddressType(paymentAddress, MAINNET)
const paymentAddressType = getAddressType(paymentAddress, network)
console.log({ paymentAddressType })
psbt.addInput({
hash: utxo.txid,
Expand All @@ -189,7 +200,7 @@ export const getCommitTx = async ({
}

if (paymentAddressType === P2SH) {
let redeemScript = getRedeemScript(paymentPublicKey!, MAINNET)
let redeemScript = getRedeemScript(paymentPublicKey!, network)
psbt.updateInput(counter, { redeemScript })
}

Expand Down Expand Up @@ -229,12 +240,14 @@ export const executeReveal = async ({
ordinalAddress,
commitTxId,
privKey,
network,
isDry,
}: {
inscriptions: { content: string; mimeType: ContentType }[]
ordinalAddress: string
commitTxId: string
privKey: string
network: NetworkType
isDry?: boolean
}) => {
try {
Expand All @@ -244,12 +257,16 @@ export const executeReveal = async ({
const tapleaf = Tap.encodeScript(script)
const [tpubkey, cblock] = Tap.getPubKey(pubKey, { target: tapleaf })

const txResult = await waitForTransaction(String(commitTxId))
const txResult = await waitForTransaction(String(commitTxId), network)
if (!txResult) {
throw new Error('ERROR WAITING FOR COMMIT TX')
}

const commitTxOutputValue = await getOutputValueByVOutIndex(commitTxId, 0)
const commitTxOutputValue = await getOutputValueByVOutIndex(
commitTxId,
0,
network
)
if (commitTxOutputValue === 0 || !commitTxOutputValue) {
throw new Error('ERROR GETTING FIRST INPUT VALUE')
}
Expand Down Expand Up @@ -279,17 +296,17 @@ export const executeReveal = async ({
return Tx.util.getTxid(txData)
}

return await broadcastTx(Tx.encode(txData).hex, MAINNET)
return await broadcastTx(Tx.encode(txData).hex, network)
} catch (e: any) {
throw e
}
}

export async function generatePrivateKey() {
export async function generatePrivateKey(network: NetworkType) {
const entropy = crypto.getRandomValues(new Uint8Array(32))
const mnemonic = bip39.entropyToMnemonic(Buffer.from(entropy))
const seed = await bip39.mnemonicToSeed(mnemonic)
const root: BIP32Interface = bip32.fromSeed(seed)
const root: BIP32Interface = bip32.fromSeed(seed, getBitcoinNetwork(network))
return root?.derivePath("m/44'/0'/0'/0/0").privateKey
}

Expand Down Expand Up @@ -353,12 +370,16 @@ export const createInscriptionScript = (

export const createRevealAddressAndKeys = (
pubKey: any,
inscriptions: { content: string; mimeType: ContentType }[]
inscriptions: { content: string; mimeType: ContentType }[],
network: NetworkType = MAINNET
) => {
const script = createInscriptionScript(pubKey, inscriptions)
const tapleaf = Tap.encodeScript(script)
const [tpubkey] = Tap.getPubKey(pubKey, { target: tapleaf })
const inscriberAddress = Address.p2tr.fromPubKey(tpubkey)
const inscriberAddress = Address.p2tr.fromPubKey(
tpubkey,
getCmDruidNetwork(network)
)

return {
inscriberAddress,
Expand Down Expand Up @@ -393,12 +414,15 @@ export async function getRawTransaction(
}
}

export async function waitForTransaction(txId: string): Promise<boolean> {
export async function waitForTransaction(
txId: string,
network: NetworkType
): Promise<boolean> {
const timeout: number = 60000
const startTime: number = Date.now()
while (true) {
try {
const rawTx: any = await getRawTransaction(txId)
const rawTx: any = await getRawTransaction(txId, network)
if (rawTx) {
console.log('Transaction found in mempool:', txId)
return true
Expand Down Expand Up @@ -431,14 +455,15 @@ export const getRecommendedFees = async (network: NetworkType) => {

export async function getOutputValueByVOutIndex(
commitTxId: string,
vOut: number
vOut: number,
network: NetworkType
): Promise<number | null> {
const timeout: number = 60000
const startTime: number = Date.now()

while (true) {
try {
const rawTx: any = await getTransaction(commitTxId)
const rawTx: any = await getTransaction(commitTxId, network)

if (rawTx && rawTx.vout && rawTx.vout.length > 0) {
return Math.floor(rawTx.vout[vOut].value)
Expand Down
1 change: 1 addition & 0 deletions packages/lasereyes-react/lib/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ export * from './wizz'
export * from './okx'
export * from './magiceden'
export * from './orange.tsx'
export * from './lasereyes-logo.tsx'

export * from './walletIcon'
Loading

0 comments on commit da03b64

Please sign in to comment.