Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/components/AppNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
IconPresentationAnalytics,
IconFileAnalytics,
IconSignature,
IconTools,
} from '@tabler/icons-react'
import { LinksGroup } from './AppNavBarLinkGroup'
import { useEffect, useState } from 'react'
Expand All @@ -22,6 +23,17 @@ const mockdata = [
icon: IconSignature,
groupLink: '/sign-message',
},
{
label: 'Utilities',
icon: IconTools,
initiallyOpened: false,
links: [
{ label: 'Address', link: '/utils/address' },
{ label: 'Encoding', link: '/utils/encoding' },
{ label: 'Amounts', link: '/utils/amounts' },
{ label: 'Block', link: '/utils/block' },
],
},
{
label: 'Fungible Tokens',
icon: IconNotes,
Expand Down
8 changes: 8 additions & 0 deletions src/components/AppShell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ import ShowMultiSig from './Multisig/ShowMultisig'
import SignMultisigTx from './Multisig/SignMultisigTx'
import BuildMultisigTx from './Multisig/BuildMultisigTx'
import NewToken from './Token/NewToken'
import AddressUtils from './Utils/AddressUtils'
import EncodingUtils from './Utils/EncodingUtils'
import AmountUtils from './Utils/AmountUtils'
import BlockUtils from './Utils/BlockUtils'

function AppShellExample() {
const theme = useMantineTheme()
Expand Down Expand Up @@ -64,6 +68,10 @@ function AppShellExample() {
<Route path="/multisig/show" element={<ShowMultiSig />} />
<Route path="/multisig/build-tx" element={<BuildMultisigTx />} />
<Route path="/multisig/sign-tx" element={<SignMultisigTx />} />
<Route path="/utils/address" element={<AddressUtils />} />
<Route path="/utils/encoding" element={<EncodingUtils />} />
<Route path="/utils/amounts" element={<AmountUtils />} />
<Route path="/utils/block" element={<BlockUtils />} />
</Routes>
</AppShell>
</Router>
Expand Down
84 changes: 84 additions & 0 deletions src/components/Multisig/BuildMultisigTx.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Button,
Center,
Chip,
Checkbox,
Grid,
Group,
Input,
Expand Down Expand Up @@ -242,6 +243,7 @@ function BuildMultisigTx() {
symbol: form.values.destinations[0].symbol,
tokenId: form.values.destinations[0].tokenId,
tokenAmount: maxBalance,
lockTime: undefined, // Sweep doesn't support lockTime
},
],
})
Expand All @@ -259,6 +261,7 @@ function BuildMultisigTx() {
symbol: form.values.destinations[0].symbol,
tokenId,
tokenAmount: number256ToNumber(tokenAmount, tokenInfo.decimals),
lockTime: form.values.destinations[0].lockTime,
},
],
})
Expand Down Expand Up @@ -463,6 +466,8 @@ function BuildMultisigTx() {
)!.id,
tokenAmount:
form.values.destinations[0].tokenAmount,
lockTime:
form.values.destinations[0].lockTime,
},
],
})
Expand All @@ -482,6 +487,7 @@ function BuildMultisigTx() {
symbol: form.values.destinations[0].symbol,
tokenId: form.values.destinations[0].tokenId,
tokenAmount: Number(value),
lockTime: form.values.destinations[0].lockTime,
},
],
})
Expand All @@ -493,6 +499,84 @@ function BuildMultisigTx() {
}}
/>
</Group>
<Group mt="lg" mx="0.5rem">
<Checkbox
label="Lock until specific time"
checked={form.values.destinations[0].lockTime !== undefined}
onChange={(e) => {
if (e.currentTarget.checked) {
// Set default to 1 hour from now
const defaultLockTime = Date.now() + 60 * 60 * 1000
form.setValues({
sweep: false,
destinations: [
{
...form.values.destinations[0],
lockTime: defaultLockTime,
},
],
})
} else {
form.setValues({
destinations: [
{
...form.values.destinations[0],
lockTime: undefined,
},
],
})
}
}}
/>
</Group>
{form.values.destinations[0].lockTime !== undefined && (
<Stack spacing="xs" mt="md" mx="0.5rem">
<TextInput
type="datetime-local"
label="Lock until (local time)"
description="Select date and time in your local timezone"
value={
form.values.destinations[0].lockTime
? new Date(form.values.destinations[0].lockTime)
.toLocaleString('sv-SE', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
})
.replace(' ', 'T')
: ''
}
onChange={(e) => {
const timestamp = new Date(e.target.value).getTime()
if (!isNaN(timestamp)) {
form.setValues({
sweep: false,
destinations: [
{
...form.values.destinations[0],
lockTime: timestamp,
},
],
})
}
}}
error={
form.values.destinations[0].lockTime &&
form.values.destinations[0].lockTime <= Date.now()
? 'Lock time must be in the future'
: undefined
}
w="16rem"
/>
{form.values.destinations[0].lockTime && (
<Text size="xs" c="dimmed">
UTC: {new Date(form.values.destinations[0].lockTime).toISOString().slice(0, 16).replace('T', ' ')} UTC
</Text>
)}
</Stack>
)}
</MyBox>
{buildTxError && (
<Text color="red" mt="lg" mx="lg">
Expand Down
22 changes: 20 additions & 2 deletions src/components/Multisig/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const defaultNewMultisigTx = {
symbol: '',
tokenId: '',
tokenAmount: undefined as number | undefined,
lockTime: undefined as number | undefined,
},
],
sweep: undefined as boolean | undefined,
Expand Down Expand Up @@ -230,13 +231,30 @@ export async function buildMultisigTx(
if (alphBalance === undefined)
tokenBalances.set(ALPH_TOKEN_ID, DUST_AMOUNT)
else tokenBalances.set(ALPH_TOKEN_ID, alphBalance + DUST_AMOUNT)
return {
const destination: {
address: string
attoAlphAmount: string
tokens: { id: string; amount: string }[]
lockTime?: number
} = {
address: d.address,
attoAlphAmount: DUST_AMOUNT.toString(),
tokens: [{ id: d.tokenId, amount: tokenAmount.toString() }],
}
if (d.lockTime !== undefined) {
destination.lockTime = d.lockTime
}
return destination
} else {
return { address: d.address, attoAlphAmount: tokenAmount.toString() }
const destination: {
address: string
attoAlphAmount: string
lockTime?: number
} = { address: d.address, attoAlphAmount: tokenAmount.toString() }
if (d.lockTime !== undefined) {
destination.lockTime = d.lockTime
}
return destination
}
})
await checkBalances(nodeProvider, config.address, tokenBalances, tokenInfos)
Expand Down
Loading
Loading