Skip to content

Commit

Permalink
payment form
Browse files Browse the repository at this point in the history
  • Loading branch information
Piefayth committed Mar 27, 2024
1 parent dc5eb14 commit 4d5ae51
Show file tree
Hide file tree
Showing 10 changed files with 927 additions and 149 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# aiken ide

idea: stop using deno or the cli to run your scripts. use a websight instead

stack: react + redux toolkit

todo:
Expand All @@ -18,4 +19,8 @@ todo:

- selectable aiken version 😭😭😭

- utilities tab for things like getting pkh, or doing to/from hex

- saving workspace to local storage

- an unimaginably long list of other stuff
48 changes: 44 additions & 4 deletions src/features/management/transactSlice.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,41 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { Spend } from '../../panels/management/transact/Transact'
import { UtxoSource } from '../../panels/management/transact/UtxoSelector'
import { SerializableAssets, SerializableUTxO } from '../../util/utxo'

export type Spend = {
source: UtxoSource,
redeemerFileName: string,
utxos: SerializableUTxO[]
}

export type Mint = {
policyId: string,
assetName: string,
amount: number // string? technically should be a bigint, but thats illegal in redux
}

export type Payment = {
toAddress: string,
datumFileName: string, // assuming inline datum atm
assets: SerializableAssets
}

interface TransactState {
addSpendError: string | undefined
spends: Spend[]
mints: Mint[]
payments: Payment[]
}

const initialState: TransactState = {
addSpendError: undefined,
spends: []
spends: [],
mints: [],
payments: []
}



const transactSlice = createSlice({
name: 'transact',
initialState,
Expand All @@ -19,9 +44,20 @@ const transactSlice = createSlice({
state.spends = [...state.spends, action.payload]
},
removeSpend(state, action: PayloadAction<number>) {
console.log(action.payload)
state.spends.splice(action.payload, 1)
},
addMint(state, action: PayloadAction<Mint>) {
state.mints = [...state.mints, action.payload]
},
removeMint(state, action: PayloadAction<number>) {
state.mints.splice(action.payload, 1)
},
addPayment(state, action: PayloadAction<Payment>) {
state.payments = [...state.payments, action.payload]
},
removePayment(state, action: PayloadAction<number>) {
state.payments.splice(action.payload, 1)
},
setAddSpendError(state, action: PayloadAction<string>) {
state.addSpendError = action.payload
},
Expand All @@ -35,6 +71,10 @@ export const {
setAddSpendError,
clearAddSpendError,
addSpend,
removeSpend
removeSpend,
addMint,
removeMint,
addPayment,
removePayment
} = transactSlice.actions
export default transactSlice.reducer
24 changes: 24 additions & 0 deletions src/panels/management/transact/Extras.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useSelector } from "react-redux"
import { RootState } from "../../../app/store"

function Extras() {
const wallets = useSelector((state: RootState) => state.management.wallets)

return (
<div className='transact-section transact-section-extra'>
<div className='transact-spend-header'>Extras</div>
<div className='transact-extras-container'>
Extra signers
{/* need list of wallet addresses */}
<br></br>
Validity interval
{/* has to use real dates :( */}
<br></br>
Metadata
{/* easy and free thank fuck */}
</div>
</div>
)
}

export { Extras }
153 changes: 153 additions & 0 deletions src/panels/management/transact/Mints.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
import { useDispatch, useSelector } from "react-redux"
import { RootState } from "../../../app/store"
import { fromText, toText } from 'lucid-cardano'
import { useLucid } from "../../../components/LucidProvider"
import { shortenAddress } from "../../../util/strings"
import { useState } from "react"
import { addMint, removeMint } from "../../../features/management/transactSlice"

function Mints() {
const dispatch = useDispatch()
const contracts = useSelector((state: RootState) => state.management.contracts)
const mints = useSelector((state: RootState) => state.transact.mints)

const [policyId, setPolicyId] = useState<string | undefined>(() => {
if (contracts.length > 0 && mints.length === 0) {
return contracts[0].scriptHash
}
})
const [assetName, setAssetName] = useState<string>('')
const [amount, setAmount] = useState<number>(0)

const { isLucidLoading, lucid: _lucid } = useLucid()
const lucid = _lucid!! // [safety] parent wont render this if (!lucid)

const isFormComplete = !!policyId && !!assetName && !!amount

return (
<div className='transact-section transact-section-mint'>
<div className='transact-spend-header'>Mint</div>
<div className='transact-spend-message-container'>
{`Minting ${mints.length} asset(s).`}
</div>
<div className='transact-mints-container'>
{
mints.map((mint, index) => {
return (
<div
key={index}
className='transact-mint-container'
>
<div className='transact-mint-policy-and-close'>
<div className='transact-mint-policy'>
{shortenAddress(mint.policyId, 4, 6)}
</div>
<div className='transact-mint-close'>
<button
className='button'
style={{ fontSize: 12 }}
onClick={() => {
dispatch(removeMint(index))
}}
>
Remove
</button>
</div>
</div>


<div className='transact-mint-body-container'>
<div className='transact-spend-source'>
<div className='input-label'>Asset Name</div>
<div className='transact-spend-source-text'>
{toText(mint.assetName)}
</div>
</div>

<div className='transact-spend-source'>
<div className='input-label'>Amount</div>
<div className='transact-spend-source-text'>
{mint.amount}
</div>
</div>
</div>
</div>
)
})
}
</div>
<div className='mint-add-container'>
<div className='mint-policy-selection-container'>
<div className='input-label'>Policy ID</div>
<select
className='mint-source-select'
value={policyId}
onChange={(e) => [
setPolicyId(e.target.value)
]}
>
{
contracts.map(contract => {
return (
<option
key={contract.scriptHash}
value={contract.scriptHash}
>
{shortenAddress(contract.scriptHash, 4, 6)}
</option>
)
})
}
</select>
</div>
<div className='mint-asset-selection-container'>
<div className='input-label'>Asset Name</div>
<input
className='text-input'
type='text'
value={assetName}
onChange={(e) => {
setAssetName(e.target.value)
}}
/>
</div>
<div className='mint-quantity-selection-container'>
<div className='input-label'>Amount</div>
<input
className='text-input'
type='number'
value={amount}
onChange={(e) => {
try {
const amount = parseInt(e.target.value)
setAmount(amount)
} catch (e) {

}
}}
/>
</div>
<div className='add-mint-button-container'>
<button
disabled={!isFormComplete}
className={`add-mint-button button ${isFormComplete ? '' : 'disabled'}`}
onClick={() => {
// TODO: Error if trying to mint the same policy + asset twice
dispatch(addMint({
policyId: policyId!!, // [safety] button is disabled if policyId is u/d
assetName: fromText(assetName),
amount
}))
setAmount(0)
setAssetName('')
}}
>Add Mint</button>
</div>

</div>

</div>
)
}

export { Mints }
Loading

0 comments on commit 4d5ae51

Please sign in to comment.