Skip to content

Commit

Permalink
fix: put all parsing and stringification into the wallet ui
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig committed Nov 5, 2020
1 parent 0e7c896 commit 58ff9a3
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 67 deletions.
3 changes: 1 addition & 2 deletions packages/dapp-svelte-wallet/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@
"dependencies": {
"@agoric/eventual-send": "^0.12.0-dev.0",
"@agoric/store": "^0.3.1-dev.0",
"esm": "^3.2.5",
"json5": "^2.1.3"
"esm": "^3.2.5"
},
"eslintConfig": {
"extends": [
Expand Down
38 changes: 5 additions & 33 deletions packages/dapp-svelte-wallet/api/src/lib-wallet.js
Original file line number Diff line number Diff line change
Expand Up @@ -177,38 +177,6 @@ export async function makeWallet({
purse,
brand,
actions: {
parseValue(str) {
const { amountMath, displayInfo } = brandTable.getByBrand(brand);
assert.typeof(
str,
'string',
details`stringValue ${str} is not a string`,
);

if (amountMath.getAmountMathKind() !== MathKind.NAT) {
// Punt to JSON5 parsing.
return JSON5.parse(str);
}

// Parse the string as a number.
const { decimalPlaces = 0 } = displayInfo || {};

const match = str.match(/^0*(\d+)(\.(\d*[1-9])?0*)?$/);
assert(
match,
details`${str} must be a non-negative decimal number`,
);

const unitstr = match[1];
const dec0str = match[3] || '';
const dec0str0 = dec0str.padEnd(decimalPlaces, '0');
assert(
dec0str0.length <= decimalPlaces,
details`${str} exceeds ${decimalPlaces} decimal places`,
);

return parseInt(`${unitstr}${dec0str0}`, 10);
},
// Send a value from this purse.
async send(receiverP, sendValue) {
const { amountMath } = brandTable.getByBrand(brand);
Expand Down Expand Up @@ -634,7 +602,11 @@ export async function makeWallet({
const purse = getPurse(pursePetname);
purseKeywordRecord[keyword] = purse;
const brand = purseToBrand.get(purse);
const amount = { brand, value };
const amount = {
brand,
value,
displayInfo: brandTable.getByBrand(brand).displayInfo,
};
return [keyword, amount];
},
),
Expand Down
1 change: 1 addition & 0 deletions packages/dapp-svelte-wallet/api/src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* @property {Petname} brandPetname
* @property {Petname} pursePetname
* @property {any} displayInfo
* @property {AmountMathKind} amountMathKind
* @property {any} value
* @property {any} currentAmountSlots
* @property {any} currentAmount
Expand Down
1 change: 1 addition & 0 deletions packages/dapp-svelte-wallet/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@agoric/captp": "^1.5.2-dev.0",
"@rollup/plugin-commonjs": "^12.0.0",
"@rollup/plugin-node-resolve": "^8.0.0",
"json5": "^2.1.3",
"livereload-js": "https://github.com/agoric-labs/livereload-js",
"rollup": "^2.3.4",
"rollup-plugin-livereload": "^1.0.0",
Expand Down
31 changes: 3 additions & 28 deletions packages/dapp-svelte-wallet/ui/src/Amount.svelte
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
<script>
import Petname from "./Petname.svelte";
import Debug from "../lib/Debug.svelte";
import Tooltip from "smelte/src/components/Tooltip";
import { stringifyValue } from './display';
export let amount;
export let displayInfo;
const CONVENTIONAL_DECIMAL_PLACES = 2;
// The amount gets updated. Make this dynamic
$: ({ brand, value } = amount);
const decimate = v => {
if (Array.isArray(v)) {
return `${v.length}`;
}
const { decimalPlaces = 0 } = displayInfo || {};
const bScale = BigInt(10) ** BigInt(decimalPlaces);
const bValue = BigInt(value);
const bDecimals = BigInt(bValue % bScale)
const bUnits = bValue / bScale;
// Convert 100 to '0000100'.
const dec0str0 = `${bDecimals}`.padStart(decimalPlaces, '0');
const dec0str = dec0str0.replace(/0+$/, '');
const decstr = dec0str.padEnd(CONVENTIONAL_DECIMAL_PLACES, '0');
const unitstr = `${bUnits}`;
if (!decstr) {
// No decimals to display.
return unitstr;
}
return `${unitstr}.${decstr}`;
};
const stringify = v => stringifyValue(v, displayInfo);
</script>

<style>
Expand Down Expand Up @@ -63,7 +38,7 @@
</Tooltip>
{:else}
<b>
{decimate(value)}
{stringify(value)}
<Petname name={brand.petname} />
</b>
{/if}
Expand Down
7 changes: 4 additions & 3 deletions packages/dapp-svelte-wallet/ui/src/Transfer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
import Button from "smelte/src/components/Button";
import Dialog from "smelte/src/components/Dialog";
import TextField from 'smelte/src/components/TextField';
import { RadioButton } from "smelte/src/components/RadioButton";
import Select from 'smelte/src/components/Select';
import { contacts, purses } from './store';
import DefaultButton from "../lib/DefaultButton.svelte";
import CancelButton from "../lib/CancelButton.svelte";
import { RadioButton } from "smelte/src/components/RadioButton";
import Select from 'smelte/src/components/Select';
import { parseValue } from './display';
export let source;
Expand All @@ -27,7 +28,7 @@
const send = async destination => {
try {
const parsed = await E(source.actions).parseValue(valueStr);
const parsed = parseValue(valueStr, source.displayInfo);
showModal = false;
await E(source.actions).send(destination.actions, parsed);
} catch (e) {
Expand Down
93 changes: 93 additions & 0 deletions packages/dapp-svelte-wallet/ui/src/display.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// @ts-check
import JSON5 from 'json5';
import { assert, details } from '@agoric/assert';
import { MathKind } from '@agoric/ertp';

const CONVENTIONAL_DECIMAL_PLACES = 2;

/**
* @typedef {{ amountMathKind?: AmountMathKind } & DisplayInfo} AmountDisplayInfo
*/

/**
*
* @param {string} str
* @param {AmountDisplayInfo} displayInfo
*/
export function parseValue(str, displayInfo) {
const { amountMathKind = MathKind.NAT, decimalPlaces = 0 } = displayInfo || {};

assert.typeof(
str,
'string',
details`valueString ${str} is not a string`,
);

if (amountMathKind !== MathKind.NAT) {
// Punt to JSON5 parsing.
return JSON5.parse(str);
}

// Parse the string as a number.
const match = str.match(/^0*(\d+)(\.(\d*[1-9])?0*)?$/);
assert(
match,
details`${str} must be a non-negative decimal number`,
);

const unitstr = match[1];
const dec0str = match[3] || '';
const dec0str0 = dec0str.padEnd(decimalPlaces, '0');
assert(
dec0str0.length <= decimalPlaces,
details`${str} exceeds ${decimalPlaces} decimal places`,
);

return parseInt(`${unitstr}${dec0str0}`, 10);
}

/**
*
* @param {any} value
* @param {AmountDisplayInfo} [displayInfo]
* @returns {string}
*/
export function stringifyValue(value, displayInfo = undefined) {
const { amountMathKind = MathKind.NAT, decimalPlaces = 0 } = displayInfo || {};

if (amountMathKind !== MathKind.NAT) {
// Just return the size of the set.
return `${value.length}`;
}

const bValue = BigInt(value);
if (!decimalPlaces) {
// Nothing else to do.
return `${bValue}`;
}

const bScale = BigInt(10) ** BigInt(decimalPlaces);

// Take integer division of the value by the scale.
const unitstr = `${bValue / bScale}`;

// Find the remainder of the value divided by the scale.
const bDecimals = BigInt(bValue % bScale)

// Create the decimal string.
const decstr = `${bDecimals}`
// Convert 100 to '0000100'.
.padStart(decimalPlaces, '0')
// Trim off trailing zeros.
.replace(/0+$/, '')
// Ensure we have at least CONVENTIONAL_DECIMAL_PLACES.
.padEnd(CONVENTIONAL_DECIMAL_PLACES, '0');

if (!decstr) {
// No decimals to display.
return `${unitstr}`;
}

// Display a decimal point with the units and decimals.
return `${unitstr}.${decstr}`;
}
2 changes: 1 addition & 1 deletion packages/zoe/src/issuerTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ const makeIssuerTable = () => {
brand,
issuer,
amountMath,
displayInfo,
displayInfo: { ...displayInfo, amountMathKind },
});
return issuerTable.getByBrand(brand);
},
Expand Down

0 comments on commit 58ff9a3

Please sign in to comment.