Skip to content

Commit

Permalink
Updates soroban-client version, updates use of helpers (#13)
Browse files Browse the repository at this point in the history
* updates soroban-client version, updates use of helpers

* cleans up not needed xdr conversions and duplicate logic

* port new helper for signing auth entries

* uses signAuthEntry while SWK adds new api

* cleans up wip helper refactors

* correctly fetched contract code expiration

* uses soroban rpc helpers to check simulation response types
  • Loading branch information
aristidesstaffieri authored Sep 25, 2023
1 parent d579993 commit b8331c2
Show file tree
Hide file tree
Showing 8 changed files with 1,133 additions and 1,077 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@
},
"dependencies": {
"@stellar/design-system": "^1.0.0-beta.12",
"@stellar/freighter-api": "^1.4.0",
"@stellar/freighter-api": "1.7.0",
"bignumber.js": "^9.1.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.14.1",
"soroban-client": "0.10.1",
"soroban-client": "1.0.0-beta.2",
"stellar-wallets-kit": "github:Creit-Tech/Stellar-Wallets-Kit"
}
}
91 changes: 51 additions & 40 deletions src/components/atomic-swap/exchange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
MemoType,
Operation,
SorobanDataBuilder,
SorobanRpc,
Transaction,
TransactionBuilder,
xdr,
Expand Down Expand Up @@ -69,7 +70,9 @@ export const Exchange = (props: ExchangeProps) => {
const [amountB, setAmountB] = React.useState("");
const [minAmountB, setMinAmountB] = React.useState("");
const [swapperBAddress, setSwapperBAddress] = React.useState("");
const [originalFootprint, setOriginalFootprint] = React.useState("");
const [originalFootprint, setOriginalFootprint] = React.useState(
null as xdr.LedgerFootprint | null,
);
const [fee, setFee] = React.useState(BASE_FEE);
const [memo, setMemo] = React.useState("");

Expand Down Expand Up @@ -152,7 +155,6 @@ export const Exchange = (props: ExchangeProps) => {
case 6: {
const submit = async () => {
const server = getServer(props.networkDetails);

setIsSubmitting(true);

const tx = TransactionBuilder.fromXDR(
Expand All @@ -162,52 +164,58 @@ export const Exchange = (props: ExchangeProps) => {

const txSim = await server.simulateTransaction(tx);

if (!SorobanRpc.isSimulationSuccess(txSim)) {
props.setError(ERRORS.TX_SIM_FAILED);
return;
}

const preparedTransaction = assembleTransaction(
tx,
props.networkDetails.networkPassphrase,
txSim,
);

const originalFootprintXDR = xdr.LedgerFootprint.fromXDR(
originalFootprint,
"base64",
);

const finalTransaction = TransactionBuilder.cloneFrom(
preparedTransaction,
)
.setSorobanData(
new SorobanDataBuilder(txSim.transactionData)
.setFootprint(
originalFootprintXDR.readOnly(),
originalFootprintXDR.readWrite(),
)
.build(),
)
.build();

const _signedXdr = await signTx(
finalTransaction.toXDR(),
props.pubKey,
props.swkKit,
);

try {
const result = await submitTx(
_signedXdr,
props.networkDetails.networkPassphrase,
server,
if (originalFootprint) {
const finalTx = preparedTransaction
.setSorobanData(
new SorobanDataBuilder(txSim.transactionData.build())
.setFootprint(
originalFootprint.readOnly(),
originalFootprint.readWrite(),
)
.build(),
)
.build();

const _signedXdr = await signTx(
finalTx.toXDR(),
props.pubKey,
props.swkKit,
);

setTxResultXDR(result);
setIsSubmitting(false);

setStepCount((stepCount + 1) as StepCount);
} catch (error) {
console.log(error);
setIsSubmitting(false);
props.setError(ERRORS.UNABLE_TO_SUBMIT_TX);
try {
const result = await submitTx(
_signedXdr,
props.networkDetails.networkPassphrase,
server,
);

setIsSubmitting(false);
if (!result) {
props.setError(ERRORS.UNABLE_TO_SUBMIT_TX);
return;
}

setTxResultXDR(result.toString());
setStepCount((stepCount + 1) as StepCount);
} catch (error) {
console.log(error);
setIsSubmitting(false);
props.setError(ERRORS.UNABLE_TO_SUBMIT_TX);
}
return;
}
props.setError(ERRORS.BAD_ENVELOPE);
};
return (
<>
Expand Down Expand Up @@ -294,7 +302,10 @@ export const Exchange = (props: ExchangeProps) => {
bc.postMessage({
type: ChannelMessageType.ContractID,
data: {
baseTx: preparedTransaction.toEnvelope().toXDR("base64"),
baseTx: preparedTransaction
.build()
.toEnvelope()
.toXDR("base64"),
contractID,
},
});
Expand Down
2 changes: 2 additions & 0 deletions src/components/atomic-swap/swapper-B.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export const SwapperB = (props: SwapperBProps) => {
signedTx,
props.networkDetails.networkPassphrase,
) as Transaction<Memo<MemoType>, Operation[]>;
console.log(tx);

const auth = await signContractAuth(
contractID,
Expand All @@ -66,6 +67,7 @@ export const SwapperB = (props: SwapperBProps) => {
props.networkDetails.networkPassphrase,
props.swkKit,
);
console.log(auth);
return auth.toEnvelope().toXDR("base64");
};

Expand Down
1 change: 1 addition & 0 deletions src/helpers/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const ERRORS = {
FREIGHTER_NOT_AVAILABLE: "Please install Freighter to connect your wallet",
UNABLE_TO_SUBMIT_TX: "Unable to submit transaction",
UNABLE_TO_SIGN_TX: "Unable to sign transaction",
TX_SIM_FAILED: "Unable to simulate transaction",
WALLET_CONNECTION_REJECTED: "Wallet connection rejected",
BAD_ENVELOPE: "Unable to unpack envelope",
CANNOT_FETCH_LEDGER_ENTRY: "Unable to fetch ledger entry",
Expand Down
17 changes: 10 additions & 7 deletions src/helpers/network.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
StellarWalletsKit,
IStellarWalletsKitSignParams,
// IStellarWalletsKitSignParams,
} from "stellar-wallets-kit";

import { signAuthEntry } from "@stellar/freighter-api";

export interface NetworkDetails {
network: string;
networkUrl: string;
Expand All @@ -17,15 +19,16 @@ export const FUTURENET_DETAILS = {
};

export const signData = async (
blob: string,
entryXdr: string,
publicKey: string,
kit: StellarWalletsKit,
) => {
const { signedXDR } = await kit.sign({
blob,
publicKey,
} as any as IStellarWalletsKitSignParams);
return signedXDR;
// TODO: go back to using kit once auth entry PR lands
console.log(kit);
const signedEntry = await signAuthEntry(entryXdr, {
accountToSign: publicKey,
});
return signedEntry;
};

export const signTx = async (
Expand Down
66 changes: 66 additions & 0 deletions src/helpers/sign-auth-entry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {
Address,
StrKey,
xdr,
nativeToScVal,
Keypair,
hash,
} from "soroban-client";

// This can be replaced with the same helper in the sdk when it lands
// https://github.com/stellar/js-stellar-base/pull/678

export async function authorizeEntry(
entry: xdr.SorobanAuthorizationEntry,
signer: (input: Buffer) => Promise<Buffer>,
validUntilLedgerSeq: any,
networkPassphrase: string,
) {
// no-op
if (
entry.credentials().switch() !==
xdr.SorobanCredentialsType.sorobanCredentialsAddress()
) {
return entry;
}

const addrAuth = entry.credentials().address();
addrAuth.signatureExpirationLedger(validUntilLedgerSeq);

const networkId = hash(Buffer.from(networkPassphrase));
const preimage = xdr.HashIdPreimage.envelopeTypeSorobanAuthorization(
new xdr.HashIdPreimageSorobanAuthorization({
networkId,
nonce: addrAuth.nonce(),
invocation: entry.rootInvocation(),
signatureExpirationLedger: addrAuth.signatureExpirationLedger(),
}),
);

const signature = await signer(preimage.toXDR());
const publicKey = Address.fromScAddress(addrAuth.address()).toString();

if (
!Keypair.fromPublicKey(publicKey).verify(hash(preimage.toXDR()), signature)
) {
throw new Error(`signature doesn't match payload`);
}

const sigScVal = nativeToScVal(
{
public_key: StrKey.decodeEd25519PublicKey(publicKey),
signature,
},
{
// force the keys to be interpreted as symbols (expected for
// Soroban [contracttype]s)
type: {
public_key: ["symbol", null],
signature: ["symbol", null],
} as any,
},
);

addrAuth.signature(xdr.ScVal.scvVec([sigScVal]));
return entry;
}
Loading

0 comments on commit b8331c2

Please sign in to comment.