Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

p10 auth #4

Merged
merged 25 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
262012b
init repo, config files, basic deps and app
aristidesstaffieri Jun 29, 2023
f4e486d
Merge remote-tracking branch 'origin'
aristidesstaffieri Jul 5, 2023
b8cc875
Merge branch 'main' of github.com:stellar/soroban-react-atomic-swap
aristidesstaffieri Jul 6, 2023
068ecde
Merge branch 'main' of github.com:stellar/soroban-react-atomic-swap
aristidesstaffieri Jul 11, 2023
c1227af
updates to current p10 changes in sdk
aristidesstaffieri Jul 11, 2023
aa2be2f
migrates to p10 auth, updates tx helpers
aristidesstaffieri Jul 12, 2023
befb3e9
migrates to sdk helpers for sc val conversions
aristidesstaffieri Jul 12, 2023
b557338
use random nonce for perimage auth, clean up redundant helpers
aristidesstaffieri Jul 13, 2023
00316d3
cleans up formatter, adds entry nonce to auth preimage
aristidesstaffieri Jul 24, 2023
670c4ac
updates to use wallet signer
aristidesstaffieri Jul 24, 2023
bb9d818
swapper signs after tx detail confirmation
aristidesstaffieri Jul 25, 2023
7560c05
correctly build contract ID key
aristidesstaffieri Jul 25, 2023
8bea512
re-prepare tx after botho signers
aristidesstaffieri Jul 25, 2023
32fe7af
upgrade soroban version, correctly build signature args
aristidesstaffieri Jul 25, 2023
c3ee845
upgrade soroban version, correctly build signature args
aristidesstaffieri Jul 25, 2023
bdf5407
cleans up debug code, removes unused broadcast channel
aristidesstaffieri Jul 27, 2023
66a93ea
cleans up use of SC helpers
aristidesstaffieri Jul 27, 2023
bb107d7
moves tx construction to exchange tab
aristidesstaffieri Jul 28, 2023
648497d
adds ID notification for exchange tab
aristidesstaffieri Jul 28, 2023
d4aac17
adds step to set memo and tx fee
aristidesstaffieri Jul 28, 2023
37fef17
adds step to set memo and tx fee
aristidesstaffieri Jul 28, 2023
2897e8e
fixes bad cast to number types for amounts, swaps BigNumber with nati…
aristidesstaffieri Jul 28, 2023
bb81444
refactors helpers to use built in constants and better semantics
aristidesstaffieri Jul 28, 2023
2a4691a
removes invalid operations check
aristidesstaffieri Jul 28, 2023
b81efce
removes invalid operations check
aristidesstaffieri Jul 28, 2023
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
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,10 @@
"dependencies": {
"@stellar/design-system": "^1.0.0-beta.12",
"@stellar/freighter-api": "^1.4.0",
"bignumber.js": "^9.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.1",
"soroban-client": "^0.8.1",
"soroban-client": "^0.9.2",
"stellar-wallets-kit": "github:Creit-Tech/Stellar-Wallets-Kit"
}
}
286 changes: 268 additions & 18 deletions src/components/atomic-swap/exchange.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
import React, { ChangeEvent } from "react";
import {
BASE_FEE,
Memo,
MemoType,
Operation,
Transaction,
TransactionBuilder,
xdr,
} from "soroban-client";
import {
Button,
Card,
Expand All @@ -18,11 +27,17 @@ import {

import { bc, ChannelMessageType } from "helpers/channel";
import { copyContent } from "helpers/dom";
import { NetworkDetails } from "helpers/network";
import { getServer, submitTx } from "helpers/soroban";
import { NetworkDetails, signTx } from "helpers/network";
import {
getServer,
submitTx,
assembleTransaction,
getTxBuilder,
buildSwap,
} from "helpers/soroban";
import { ERRORS } from "../../helpers/error";

type StepCount = 1 | 2 | 3 | 4;
type StepCount = 1 | 2 | 3 | 4 | 5 | 6 | 7;

interface ExchangeProps {
networkDetails: NetworkDetails;
Expand All @@ -38,24 +53,38 @@ export const Exchange = (props: ExchangeProps) => {
const [isSubmitting, setIsSubmitting] = React.useState(false);
const [stepCount, setStepCount] = React.useState(1 as StepCount);

const [exchangeKey, setExchangeKey] = React.useState("");

const [tokenAAddress, setTokenAAddress] = React.useState("");
const [amountA, setAmountA] = React.useState("");
const [minAmountA, setMinAmountA] = React.useState("");
const [tokenBAddress, setTokenBAddress] = React.useState("");
const [amountB, setAmountB] = React.useState("");
const [minAmountB, setMinAmountB] = React.useState("");
const [swapperBAddress, setSwapperBAddress] = React.useState("");
const [originalFootprint, setOriginalFootprint] = React.useState("");
const [fee, setFee] = React.useState(BASE_FEE);
const [memo, setMemo] = React.useState("");

bc.onmessage = (messageEvent) => {
const { data, type } = messageEvent.data;

switch (type) {
case ChannelMessageType.SignedTx: {
setSignedTx(data.signedTx);
setStepCount(3);
setStepCount(5);
return;
}
default:
console.log("message type unknown");
console.log(`message type unknown, ignoring ${type}`);
}
};

const connect = async () => {
const connect = () => {
props.setError(null);

// See https://github.com/Creit-Tech/Stellar-Wallets-Kit/tree/main for more options
await props.swkKit.openModal({
props.swkKit.openModal({
allowedWallets: [
WalletType.ALBEDO,
WalletType.FREIGHTER,
Expand All @@ -67,10 +96,12 @@ export const Exchange = (props: ExchangeProps) => {
props.swkKit.setWallet(option.type);
const publicKey = await props.swkKit.getPublicKey();

await props.swkKit.setNetwork(WalletNetwork.FUTURENET);
props.swkKit.setNetwork(WalletNetwork.FUTURENET);

// also set pubkey in parent to display active profile
props.setPubKey(publicKey);
setExchangeKey(publicKey);

setStepCount((stepCount + 1) as StepCount);
} catch (error) {
console.log(error);
Expand All @@ -82,7 +113,7 @@ export const Exchange = (props: ExchangeProps) => {

function renderStep(step: StepCount) {
switch (step) {
case 4: {
case 7: {
return (
<>
<Heading as="h1" size="sm" addlClassName="title">
Expand Down Expand Up @@ -114,15 +145,36 @@ export const Exchange = (props: ExchangeProps) => {
</>
);
}
case 3: {
case 6: {
const submit = async () => {
const server = getServer(props.networkDetails);

setIsSubmitting(true);

const tx = TransactionBuilder.fromXDR(
signedTx,
props.networkDetails.networkPassphrase,
) as Transaction<Memo<MemoType>, Operation[]>;

const txSim = await server.simulateTransaction(tx);
const preparedTransaction = assembleTransaction(
tx,
props.networkDetails.networkPassphrase,
txSim,
xdr.LedgerFootprint.fromXDR(
Buffer.from(originalFootprint, "base64"),
),
aristidesstaffieri marked this conversation as resolved.
Show resolved Hide resolved
);

const _signedXdr = await signTx(
preparedTransaction.toXDR(),
exchangeKey,
props.swkKit,
);

try {
const result = await submitTx(
signedTx,
_signedXdr,
props.networkDetails.networkPassphrase,
server,
);
Expand Down Expand Up @@ -164,11 +216,49 @@ export const Exchange = (props: ExchangeProps) => {
</>
);
}
case 2: {
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setContractID(event.target.value);
case 5: {
const handleFeeChange = (event: ChangeEvent<HTMLInputElement>) => {
setFee(event.target.value);
};
const handleMemoChange = (event: ChangeEvent<HTMLInputElement>) => {
setMemo(event.target.value);
};
const goToSwapperA = () => {

const goToSwapperA = async () => {
const server = getServer(props.networkDetails);
// Gets a transaction builder and use it to add a "swap" operation and build the corresponding XDR
const txBuilder = await getTxBuilder(
exchangeKey,
BASE_FEE,
server,
props.networkDetails.networkPassphrase,
);

const tokenA = {
id: tokenAAddress,
amount: BigInt(amountA).toString(),
minAmount: BigInt(minAmountA).toString(),
};

const tokenB = {
id: tokenBAddress,
amount: BigInt(amountB).toString(),
minAmount: BigInt(minAmountB).toString(),
};

const { preparedTransaction, footprint } = await buildSwap(
contractID,
tokenA,
tokenB,
exchangeKey,
swapperBAddress,
memo,
server,
props.networkDetails.networkPassphrase,
txBuilder,
);
setOriginalFootprint(footprint);

const newWindow = window.open(
`${window.location.origin}/swapper-a`,
"_blank",
Expand All @@ -177,11 +267,171 @@ export const Exchange = (props: ExchangeProps) => {
newWindow.onload = () => {
bc.postMessage({
type: ChannelMessageType.ContractID,
data: contractID,
data: {
baseTx: preparedTransaction.toEnvelope().toXDR("base64"),
contractID,
},
});
};
}
};

return (
<>
<Heading as="h1" size="sm">
Payment Settings
</Heading>
<Input
fieldSize="md"
id="input-fee"
label="Estimated Fee (XLM)"
value={fee}
onChange={handleFeeChange}
/>
<Input
fieldSize="md"
id="input-memo"
label="Memo"
value={memo}
onChange={handleMemoChange}
/>
<div className="submit-row-fee">
<Button
size="md"
variant="tertiary"
isFullWidth
onClick={goToSwapperA}
>
Build Swap
</Button>
</div>
</>
);
}
case 4: {
const handleSwapperBAddress = (
event: ChangeEvent<HTMLInputElement>,
) => {
setSwapperBAddress(event.target.value);
};
const handleTokenBChange = (event: ChangeEvent<HTMLInputElement>) => {
setTokenBAddress(event.target.value);
};
const handleTokenBAmountChange = (
event: ChangeEvent<HTMLInputElement>,
) => {
setAmountB(event.target.value);
};
const handleTokenBMinAmountChange = (
event: ChangeEvent<HTMLInputElement>,
) => {
setMinAmountB(event.target.value);
};

return (
<>
<Heading as="h1" size="sm">
Choose Token B
</Heading>
<Input
fieldSize="md"
id="swapper-b-address"
label="Swapper B Address"
value={swapperBAddress}
onChange={handleSwapperBAddress}
/>
<Input
fieldSize="md"
id="token-b-id"
label="Token ID"
value={tokenBAddress}
onChange={handleTokenBChange}
/>
<Input
fieldSize="md"
id="token-b-amount"
label="Amount"
value={amountB}
onChange={handleTokenBAmountChange}
/>
<Input
fieldSize="md"
id="token-b-min-amount"
label="Min Amount"
value={minAmountB}
onChange={handleTokenBMinAmountChange}
/>
<div className="submit-row">
<Button
size="md"
variant="tertiary"
isFullWidth
onClick={() => setStepCount((stepCount + 1) as StepCount)}
>
Next
</Button>
</div>
</>
);
}
case 3: {
const handleTokenAChange = (event: ChangeEvent<HTMLInputElement>) => {
setTokenAAddress(event.target.value);
};
const handleTokenAAmountChange = (
event: ChangeEvent<HTMLInputElement>,
) => {
setAmountA(event.target.value);
};
const handleTokenAMinAmountChange = (
event: ChangeEvent<HTMLInputElement>,
) => {
setMinAmountA(event.target.value);
};

return (
<>
<Heading as="h1" size="sm">
Choose Token A
</Heading>
<Input
fieldSize="md"
id="token-a-id"
label="Token ID"
value={tokenAAddress}
onChange={handleTokenAChange}
/>
<Input
fieldSize="md"
id="token-a-amount"
label="Amount"
value={amountA}
onChange={handleTokenAAmountChange}
/>
<Input
fieldSize="md"
id="token-a-min-amount"
label="Min Amount"
value={minAmountA}
onChange={handleTokenAMinAmountChange}
/>
<div className="submit-row">
<Button
size="md"
variant="tertiary"
isFullWidth
onClick={() => setStepCount((stepCount + 1) as StepCount)}
>
Next
</Button>
</div>
</>
);
}
case 2: {
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
setContractID(event.target.value);
};
return (
<>
<Heading as="h1" size="sm">
Expand All @@ -199,9 +449,9 @@ export const Exchange = (props: ExchangeProps) => {
size="md"
variant="tertiary"
isFullWidth
onClick={goToSwapperA}
onClick={() => setStepCount((stepCount + 1) as StepCount)}
>
Go to Swapper A
Next
</Button>
</div>
</>
Expand Down
Loading