Skip to content

Commit

Permalink
[Draft] Spacewalk mykobo prototype phase 1 (#21)
Browse files Browse the repository at this point in the history
* first steps

* WIP

* first iteration prototype ui

* some UI changes for events, input box

* remove mock testing code

* Add `.husky` files to fix precommit hook

* Remove linting from `lint-staged`

* Run `yarn format`

* wrap log text

* Break text in event boxes

* align event text

* lint issues, cleaner stellar error text display

* more lint ts changes

* Fix 'no-async-promise-executor' issue

* Fix missing hook deps

* Fix bad refactoring of promise

* don't use iframe

* different big number library that handles decimals also

* print ephemeral secret

* load ephemeral account only once for transaction creation

* remove unused bignumber libraries

---------

Co-authored-by: Marcel Ebert <mail@marcel-ebert.de>
  • Loading branch information
gianfra-t and ebma authored Apr 24, 2024
1 parent bbad9b7 commit 9996021
Show file tree
Hide file tree
Showing 26 changed files with 1,749 additions and 65 deletions.
1 change: 1 addition & 0 deletions .husky/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
150 changes: 150 additions & 0 deletions App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
html, body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
overflow-x: hidden;
}

#app {
width: 100%;
min-width: 1800px;
box-sizing: border-box;
}


.inputBox {
width: 30%;
margin: 20px auto;
padding: 20px;
border: 1px solid #ccc;
box-shadow: 0 0 10px #ccc;
transition: all 0.5s ease-in-out;
display: flex;
flex-direction: column;
align-items: center;
}

.inputBox.active {
width: 21%;
margin-top: 5px;
}

.inputBox input:disabled {
background-color: #ccc;
color: #666;
}
.eventsContainer {
display: flex;
flex-direction: column;
align-items: center;
overflow-y: scroll;
max-height: 70vh;
}

input {
margin: 10px;
padding: 10px;
}

.eventBox {
margin: 20px auto;
width: 30%;
padding: 20px;
border: 1px solid #ccc;
box-shadow: 0 0 10px #ccc;
transition: all 0.5s ease-in-out;
color: #333;
word-wrap: break-word;
text-align: center;
}

.eventBox.waiting {
background-color: #ffffff;
border-color: #ccc;
}

.eventBox.active.waiting {
/*animation: rotateShadowBlue 5s linear infinite;*/
border-color: #ffffff;
}

/* @keyframes rotateShadowBlue {
0% { box-shadow: 0 0 15px #007bff; }
25% { box-shadow: 15px 0 15px #007bff; }
50% { box-shadow: 0 15px 15px #007bff; }
75% { box-shadow: -15px 0 15px #007bff; }
100% { box-shadow: 0 -15px 15px #007bff; }
} */

.eventBox.success {
background-color: #d4edda;
border-color: #c3e6cb;
}

.eventBox.active {
transform: scale(1.3);
background-color: #f0f0f0;
}

.eventBox.error {
margin: 20px auto;
width: 30%;
padding: 20px;
border: 1px solid #ccc;
box-shadow: 0 0 10px #ccc;
transition: all 0.5s ease-in-out;
color: red;
background-color: #f8d7da;
border-color: #f5c6cb;
color: red;
}

.iframe-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-top: 50px;
}

button {
padding: 10px 20px;
cursor: pointer;
margin-top: 20px;
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
transition: background-color 0.3s, transform 0.3s;
}

button:hover {
background-color: #0056b3;
transform: scale(1.05);
}

.description {
color: #666;
font-size: 14px;
margin-bottom: 10px;
}

.icons {
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}

.icon {
width: 30px;
height: 30px;
}

.arrow {
width: 50px;
margin: 0 10px;
}
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# PendulumPay

[//]: # ([![Netlify Status]&#40;https://api.netlify.com/api/v1/badges/aa69406a-f4a1-4693-aed0-8478f1d1fabd/deploy-status&#41;]&#40;https://app.netlify.com/sites/pendulum-portal-alpha/deploys&#41;)
[//]:
#
'[![Netlify Status](https://api.netlify.com/api/v1/badges/aa69406a-f4a1-4693-aed0-8478f1d1fabd/deploy-status)](https://app.netlify.com/sites/pendulum-portal-alpha/deploys)'

&nbsp; ![TypeScript](https://img.shields.io/badge/-TypeSript-05122A?style=flat&logo=typescript)&nbsp;
![Preact](https://img.shields.io/badge/-Preact-05122A?style=flat&logo=preact)&nbsp;
![Vite](https://img.shields.io/badge/-Vite-05122A?style=flat&logo=vite)&nbsp;
Expand All @@ -9,8 +12,7 @@

---

PendulumPay is a gateway for cross-border payments.
It is built on top of the Pendulum blockchain.
PendulumPay is a gateway for cross-border payments. It is built on top of the Pendulum blockchain.

## Run

Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@
"@polkadot/rpc-provider": "^9.9.1",
"@polkadot/types": "^9.9.1",
"@polkadot/util": "^10.1.9",
"bn.js": "^5.2.1",
"big.js": "^6.2.1",
"buffer": "^6.0.3",
"preact": "^10.12.1",
"react-router-dom": "^6.8.1"
"react-router-dom": "^6.8.1",
"stellar-base": "^11.0.1",
"stellar-sdk": "^11.3.0"
},
"devDependencies": {
"@babel/core": "^7.20.12",
Expand All @@ -54,7 +57,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/preact": "^3.2.3",
"@testing-library/preact-hooks": "^1.1.0",
"@types/bn.js": "^5",
"@types/big.js": "^6",
"@types/jest": "^29.4.0",
"@types/node": "^18.14.1",
"@types/react": "^18.0.28",
Expand All @@ -79,7 +82,6 @@
"yarn": ">=1.22.19"
},
"lint-staged": {
"*.{ts,tsx}": "eslint --cache --fix",
"*.--write": "prettier --write"
}
}
1 change: 1 addition & 0 deletions src/assets/coins/arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/assets/coins/eurc.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/assets/coins/euro.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions src/components/GenericEvent/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

export enum EventStatus {
Success = 'success',
Error = 'error',
Waiting = 'waiting',
}

export interface GenericEvent {
value: string;
status: EventStatus;
}

interface EventBoxProps {
event: GenericEvent;
className: string;
}

const EventBox = React.forwardRef<HTMLDivElement, EventBoxProps>(({ event, className }, ref) => {
const classes = `eventBox ${className} ${event.status}`;

return (
<div ref={ref} className={classes}>
<p>{event.value}</p>
</div>
);
});

export default EventBox;
88 changes: 88 additions & 0 deletions src/components/InputKeys/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { useState } from 'react';
import { checkStellarAccount } from '../../services/stellar/utils';
import { checkPendulumAccount } from '../../services/polkadot/utils';
import eurcSvg from '../../assets/coins/eurc.svg';
import euroSvg from '../../assets/coins/euro.svg';
import arrowSvg from '../../assets/coins/arrow.svg';
export interface IInputBoxData {
stellarFundingSecret: string;
pendulumSecret: string;
}

interface InputBoxProps {
onSubmit: (secrets: IInputBoxData) => void;
}

const InputBox: React.FC<InputBoxProps> = ({ onSubmit }) => {
const [stellarFundingSecret, setStellarFundingSecret] = useState<string>('');
const [pendulumSecret, setPendulumSecret] = useState<string>('');
const [isSubmitted, setIsSubmitted] = useState<boolean>(false);

const [stellarError, setStellarError] = useState<string>('');
const [pendulumError, setPendulumError] = useState<string>('');

const handleSubmit = async () => {
const stellarResult = await checkStellarAccount(stellarFundingSecret);

const pendulumResult = await checkPendulumAccount(pendulumSecret);

if (stellarResult && pendulumResult) {
setIsSubmitted(true);
onSubmit({ stellarFundingSecret, pendulumSecret });
} else {
if (!stellarResult) {
setStellarError('Please check the stellar secret');
}
if (!pendulumResult) {
setPendulumError('Please check the pendulum secret');
}
console.error('One or both accounts do not exist or have insufficient balance.');
}
};

return (
<div>
<div className="icons">
<img src={eurcSvg} className="icon" alt="Icon X" />
<img src={arrowSvg} className="arrow" alt="Arrow" />
<img src={euroSvg} className="icon" alt="Icon Y" />
</div>
<div className={`inputBox ${isSubmitted ? 'active' : ''}`}>
{!isSubmitted && (
<div className="description">
Enter your secrets below to start the offramp process.
<ul>
<li>Ensure to have enough EURC in Pendulum for the desired amount to offramp.</li>
<li>Do not close this window until the process is completed.</li>
</ul>
</div>
)}
<input
type="password"
value={stellarFundingSecret}
onChange={(e) => {
setStellarFundingSecret((e.target as HTMLInputElement).value);
if (stellarError) setStellarError('');
}}
placeholder="Stellar Funding Secret"
disabled={isSubmitted}
/>
{stellarError && <div style={{ color: 'red' }}>{stellarError}</div>}
<input
type="password"
value={pendulumSecret}
onChange={(e) => {
setPendulumSecret((e.target as HTMLInputElement).value);
if (pendulumError) setPendulumError('');
}}
placeholder="Pendulum Secret"
disabled={isSubmitted}
/>
{pendulumError && <div style={{ color: 'red' }}>{pendulumError}</div>}
{!isSubmitted ? <button onClick={handleSubmit}>Begin Offramp</button> : <div>Offramp Started</div>}
</div>
</div>
);
};

export default InputBox;
Loading

0 comments on commit 9996021

Please sign in to comment.