Skip to content

Commit

Permalink
Allow Decimal Values (#367) (#375)
Browse files Browse the repository at this point in the history
* Allow Decimal Values

* show error when decimal values > 10

Co-authored-by: Abdulrahim Al Methiab <[email protected]>
  • Loading branch information
arty-name and abdulmth authored Dec 4, 2024
1 parent 53db308 commit c932b3a
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 33 deletions.
14 changes: 7 additions & 7 deletions src/components/bounty-setup/BountyCreation.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { createEventDispatcher } from 'svelte';
import type { BountyInfo } from '../../types/bounty';
import { activeAccount, dotApi } from '../../stores';
import { convertDotToPlanck, formatPlanckToDot } from '../../utils/polkadot';
import { isInteger } from '../../utils/common';
import { convertFormattedDotToPlanck, formatPlanckToDot } from '../../utils/polkadot';
import { isPositiveNumber } from '../../utils/common';
import { showErrorDialog } from '../../utils/loading-screen';
import { Binary } from 'polkadot-api';
import { calculateTransactionFee, submitTransaction } from '../../utils/transaction';
Expand Down Expand Up @@ -36,12 +36,12 @@
showErrorDialog('Bounty value is invalid');
return;
}
if (!isInteger(bountyValue)) {
if (!isPositiveNumber(bountyValue)) {
showErrorDialog('Bounty value is invalid');
return;
}
const value = convertDotToPlanck(BigInt(bountyValue));
const value = convertFormattedDotToPlanck(bountyValue);
const description = bountyTitle;
const transaction = $dotApi.tx.Bounties.propose_bounty({
value,
Expand Down Expand Up @@ -85,7 +85,7 @@
async function calculateFee() {
try {
if (bountyValue && bountyTitle && $activeAccount) {
const value = convertDotToPlanck(BigInt(bountyValue));
const value = convertFormattedDotToPlanck(bountyValue);
const description = bountyTitle;
const transaction = $dotApi.tx.Bounties.propose_bounty({
value,
Expand All @@ -104,7 +104,7 @@
async function calculateBond() {
try {
if (bountyValue && bountyTitle && $activeAccount) {
const value = convertDotToPlanck(BigInt(bountyValue));
const value = convertFormattedDotToPlanck(bountyValue);
const description = bountyTitle;
const transaction = $dotApi.tx.Bounties.propose_bounty({
value,
Expand Down Expand Up @@ -184,7 +184,7 @@
<input
bind:value={bountyValue}
class="border pt-1 pl-2 w-full md:w-1/3 rounded-md bg-white"
placeholder="1000"
placeholder="1000.00"
on:input={inputChange}
/>
</section>
Expand Down
14 changes: 9 additions & 5 deletions src/components/bounty-setup/CuratorProposal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
import type { BountyInfo } from '../../types/bounty';
import { activeAccount, dotApi } from '../../stores';
import { treasuryTracks } from './treasuryTracks';
import { convertDotToPlanck, formatPlanckToDot, isValidAddress } from '../../utils/polkadot';
import { isInteger } from '../../utils/common';
import {
convertFormattedDotToPlanck,
formatPlanckToDot,
isValidAddress
} from '../../utils/polkadot';
import { isPositiveNumber } from '../../utils/common';
import { onMount } from 'svelte';
import { showErrorDialog, showLoadingDialog } from '../../utils/loading-screen';
import {
Expand Down Expand Up @@ -46,7 +50,7 @@
return;
}
if (!curatorFee || !isInteger(curatorFee)) {
if (!curatorFee || !isPositiveNumber(curatorFee)) {
showErrorDialog('Invalid value of curator fee');
return;
}
Expand All @@ -71,7 +75,7 @@
const transaction = $dotApi.tx.Bounties.propose_curator({
bounty_id: bountyInfo.id,
curator: MultiAddress.Id(curatorAddress),
fee: convertDotToPlanck(BigInt(curatorFee))
fee: convertFormattedDotToPlanck(curatorFee)
});
const proposal: PreimagesBounded = PreimagesBounded.Inline(
Binary.fromBytes((await transaction.getEncodedData()).asBytes())
Expand Down Expand Up @@ -178,7 +182,7 @@
<p class="text-xs my-1">Curator Fee</p>
<input
bind:value={curatorFee}
placeholder="0"
placeholder="00.00"
on:input={inputChange}
class="pt-1 pl-2 rounded-md bg-white mr-2 w-full md:w-1/3"
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import type { Bounty } from '../../../../types/bounty';
import { convertDotToPlanck } from '../../../../utils/polkadot';
import { convertFormattedDotToPlanck } from '../../../../utils/polkadot';
import { activeAccount, dotApi } from '../../../../stores';
import { onMount } from 'svelte';
import { showErrorDialog } from '../../../../utils/loading-screen';
import { isInteger } from '../../../../utils/common';
import { isPositiveNumber } from '../../../../utils/common';
import PolkaCoin from '../../../svg/PolkaCoin.svg';
import Dialog from '../../../common/Dialog.svelte';
import { Binary } from 'polkadot-api';
Expand All @@ -29,12 +29,12 @@
showErrorDialog('Bounty title is empty');
return;
}
if (!bountyValue || !isInteger(bountyValue)) {
if (!bountyValue || !isPositiveNumber(bountyValue)) {
showErrorDialog('Bounty value is invalid');
return;
}
const value = convertDotToPlanck(BigInt(bountyValue));
const value = convertFormattedDotToPlanck(bountyValue);
const transaction = $dotApi.tx.ChildBounties.add_child_bounty({
parent_bounty_id: bounty.id,
value,
Expand All @@ -47,7 +47,7 @@
async function calculateFee() {
try {
if (bountyValue && bountyTitle && $activeAccount) {
const value = convertDotToPlanck(BigInt(bountyValue));
const value = convertFormattedDotToPlanck(bountyValue);
const transaction = $dotApi.tx.ChildBounties.add_child_bounty({
parent_bounty_id: bounty.id,
value,
Expand Down Expand Up @@ -100,7 +100,7 @@
<input
bind:value={bountyValue}
class="border border-black pt-1 pl-2 rounded-[3px] bg-white h-10 w-full"
placeholder="0"
placeholder="00.00"
on:input={inputChange}
/>
<div class="border border-accent absolute right-9 top-9 transform -translate-y-1/2 h-6"></div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<script lang="ts">
import { convertDotToPlanck, isValidAddress } from '../../../../utils/polkadot';
import { convertFormattedDotToPlanck, isValidAddress } from '../../../../utils/polkadot';
import { activeAccount, dotApi } from '../../../../stores';
import { onMount } from 'svelte';
import { showErrorDialog } from '../../../../utils/loading-screen';
import type { ChildBounty } from '../../../../types/child-bounty';
import { isInteger } from '../../../../utils/common';
import { isPositiveNumber } from '../../../../utils/common';
import PolkaCoin from '../../../svg/PolkaCoin.svg';
import Dialog from '../../../common/Dialog.svelte';
import { MultiAddress } from '@polkadot-api/descriptors';
Expand All @@ -28,7 +28,7 @@
return;
}
if (!isInteger(curatorFee)) {
if (!isPositiveNumber(curatorFee)) {
showErrorDialog('Curator fee value is invalid');
return;
}
Expand All @@ -37,7 +37,7 @@
parent_bounty_id: childBounty.parentBounty,
child_bounty_id: childBounty.id,
curator: MultiAddress.Id(curatorAddress),
fee: convertDotToPlanck(BigInt(curatorFee))
fee: convertFormattedDotToPlanck(curatorFee)
});
await submitTransaction(transaction);
}
Expand All @@ -52,7 +52,7 @@
parent_bounty_id: childBounty.parentBounty,
child_bounty_id: childBounty.id,
curator: MultiAddress.Id($activeAccount.address),
fee: convertDotToPlanck(BigInt(curatorFee))
fee: convertFormattedDotToPlanck(curatorFee)
});
fee = (await calculateTransactionFee(transaction)) + ' DOT';
} catch (e) {
Expand Down Expand Up @@ -86,7 +86,7 @@
<input
bind:value={curatorFee}
class="border border-primary rounded-[3px] bg-white pl-2 pt-1 h-10 w-full"
placeholder="0"
placeholder="00.00"
/>
<div class="border border-accent absolute right-9 top-9 transform -translate-y-1/2 h-6"></div>
<div class="absolute right-2 top-[26px]">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script lang="ts">
import { convertDotToPlanck, isValidAddress } from '../../../../utils/polkadot';
import { convertFormattedDotToPlanck, isValidAddress } from '../../../../utils/polkadot';
import Dialog from '../../../common/Dialog.svelte';
import { activeAccount, dotApi } from '../../../../stores';
import { onMount } from 'svelte';
import { showErrorDialog, showLoadingDialog } from '../../../../utils/loading-screen';
import type { ChildBounty } from '../../../../types/child-bounty';
import { isInteger } from '../../../../utils/common';
import { isPositiveNumber } from '../../../../utils/common';
import PolkaCoin from '../../../svg/PolkaCoin.svg';
import { MultiAddress } from '@polkadot-api/descriptors';
import { calculateTransactionFee, submitTransaction } from '../../../../utils/transaction';
Expand Down Expand Up @@ -33,7 +33,7 @@
return;
}
if (!isInteger(curatorFee)) {
if (!isPositiveNumber(curatorFee)) {
showErrorDialog('Curator fee value is invalid');
return;
}
Expand All @@ -42,7 +42,7 @@
parent_bounty_id: childBounty.parentBounty,
child_bounty_id: childBounty.id,
curator: MultiAddress.Id($activeAccount.address),
fee: convertDotToPlanck(BigInt(curatorFee))
fee: convertFormattedDotToPlanck(curatorFee)
});
const tx2 = $dotApi.tx.ChildBounties.accept_curator({
Expand Down Expand Up @@ -78,7 +78,7 @@
parent_bounty_id: childBounty.parentBounty,
child_bounty_id: childBounty.id,
curator: MultiAddress.Id($activeAccount.address),
fee: convertDotToPlanck(BigInt(curatorFee))
fee: convertFormattedDotToPlanck(curatorFee)
});
const tx2 = $dotApi.tx.ChildBounties.accept_curator({
Expand Down Expand Up @@ -127,7 +127,7 @@
<input
bind:value={curatorFee}
class="border border-primary rounded-[3px] bg-white pl-2 pt-1 h-10 w-full"
placeholder="0"
placeholder="00.00"
/>
<div class="border border-accent absolute right-9 top-9 transform -translate-y-1/2 h-6"></div>
<div class="absolute right-2 top-[26px]">
Expand Down
15 changes: 12 additions & 3 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { getCurrentBlock } from './polkadot';

export function isInteger(input: string): boolean {
const num = parseInt(input, 10);
return Number.isInteger(num) && num.toString() === input;
/**
* @returns `true` if `input` represents a positive integer or decimal number
* and the number of decimal places does not exceed `maxPrecision`.
*/
export function isPositiveNumber(input: string, maxPrecision = 10): boolean {
const positiveNumberRegex = /^\d+(\.\d+)?$/;
if (!positiveNumberRegex.test(input)) {
return false;
}

const decimalPart = input.split('.')[1] || '';
return decimalPart.length <= maxPrecision;
}

export function truncateString(input: string, maxLength: number) {
Expand Down
19 changes: 19 additions & 0 deletions src/utils/polkadot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,32 @@ import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat';
import { AccountId, createClient, getSs58AddressInfo } from 'polkadot-api';
import { dot } from '@polkadot-api/descriptors';
import { getWsProvider } from 'polkadot-api/ws-provider/web';
import { isPositiveNumber } from './common';

export function createTypedApi(nodeEndpoint: string) {
const sdkProvider = withPolkadotSdkCompat(getWsProvider(nodeEndpoint));
const sdkClient = createClient(sdkProvider);
return sdkClient.getTypedApi(dot);
}

export function convertFormattedDotToPlanck(value: string): bigint {
if (!isPositiveNumber(value)) {
throw new Error('Provided value is invalid');
}

const parts = value.split('.');
const integerPartInPlanck: bigint = convertDotToPlanck(BigInt(parts[0]));
let decimalPart = parts[1] || '';

if (decimalPart === '') {
return integerPartInPlanck;
}
decimalPart = decimalPart.padEnd(10, '0');
const decimalPartInPlack = BigInt(decimalPart);

return integerPartInPlanck + decimalPartInPlack;
}

export function convertDotToPlanck(value: bigint): bigint {
return value * BigInt(1e10);
}
Expand Down

0 comments on commit c932b3a

Please sign in to comment.