Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
mPaella committed Sep 14, 2023
1 parent a20e808 commit b693e8d
Show file tree
Hide file tree
Showing 5 changed files with 446 additions and 29 deletions.
6 changes: 4 additions & 2 deletions packages/core/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
},
"dependencies": {
"exponential-backoff": "3.1.1",
"uuid": "9.0.0"
"uuid": "9.0.1"
},
"devDependencies": {
"@types/uuid": "9.0.3"
"@ethersproject/transactions": "5.7.0",
"@solana/web3.js": "1.78.5",
"@types/uuid": "9.0.4"
}
}
31 changes: 25 additions & 6 deletions packages/core/base/src/types/embed/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,34 @@
import type { Transaction as _EthersTransaction } from "@ethersproject/transactions";
import type { Transaction as _SolanaTransaction } from "@solana/web3.js";

import { CommonEmbeddedCheckoutProps } from ".";
import { CryptoPaymentMethod } from "..";

export type CryptoEmbeddedCheckoutProps<
type CryptoEmbeddedCheckoutPropsBase<
PM extends keyof CryptoPaymentMethodSignerMap = keyof CryptoPaymentMethodSignerMap,
> = CommonEmbeddedCheckoutProps<PM> & {
paymentMethod: PM;
signer?: CryptoPaymentMethodSignerMap[PM];
};

export type CryptoEmbeddedCheckoutPropsWithSigner<
type CryptoEmbeddedCheckoutPropsWithSignerBase<
PM extends keyof CryptoPaymentMethodSignerMap = keyof CryptoPaymentMethodSignerMap,
> = CommonEmbeddedCheckoutProps<PM> & {
> = CryptoEmbeddedCheckoutPropsBase<PM> & {
signer: CryptoPaymentMethodSignerMap[PM];
};

// Union discriminate with required signer
export type CryptoEmbeddedCheckoutPropsWithSigner = {
[PM in keyof CryptoPaymentMethodSignerMap]: CryptoEmbeddedCheckoutPropsWithSignerBase<PM>;
}[keyof CryptoPaymentMethodSignerMap];

// Union discriminate type - both with or without signer
export type CryptoEmbeddedCheckoutProps =
| {
[PM in keyof CryptoPaymentMethodSignerMap]: CryptoEmbeddedCheckoutPropsBase<PM>;
}[keyof CryptoPaymentMethodSignerMap]
| CryptoEmbeddedCheckoutPropsWithSigner;

type CryptoPaymentMethodSignerMap = {
[CryptoPaymentMethod.ETH]: ETHEmbeddedCheckoutSigner;
[CryptoPaymentMethod.SOL]: SOLEmbeddedCheckoutSigner;
Expand All @@ -22,12 +38,15 @@ type CommonEmbeddedCheckoutSignerProps = {
address: string;
};

// Aliases to preserve names
type EthersTransaction = _EthersTransaction;
type SolanaTransaction = _SolanaTransaction;

// Signers
// TODO: Import proper types from respective packages
export type ETHEmbeddedCheckoutSigner = CommonEmbeddedCheckoutSignerProps & {
signAndSendTransaction: (transaction: any) => Promise<string>;
signAndSendTransaction: (transaction: EthersTransaction) => Promise<string>;
};

export type SOLEmbeddedCheckoutSigner = CommonEmbeddedCheckoutSignerProps & {
signAndSendTransaction: (transaction: any) => Promise<string>;
signAndSendTransaction: (transaction: SolanaTransaction) => Promise<string>;
};
3 changes: 3 additions & 0 deletions packages/ui/react-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
},
"dependencies": {
"@crossmint/client-sdk-base": "1.1.0-alpha.0",
"@ethersproject/transactions": "5.7.0",
"@solana/web3.js": "1.78.5",
"bs58": "5.0.0",
"react-jss": "10.10.0"
},
"peerDependencies": {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import bs58 from "bs58";

import {
CryptoEmbeddedCheckoutPropsWithSigner,
ETHEmbeddedCheckoutSigner,
IncomingInternalEvent,
SOLEmbeddedCheckoutSigner,
crossmintIFrameService,
} from "@crossmint/client-sdk-base";

Expand All @@ -9,20 +13,31 @@ import CrossmintEmbeddedCheckoutIFrame from "../EmbeddedCheckoutIFrame";
export default function CryptoEmbeddedCheckoutIFrame(props: CryptoEmbeddedCheckoutPropsWithSigner) {
const { emitInternalEvent } = crossmintIFrameService(props);

const { signer } = props;
const { signer, paymentMethod } = props;

function onInternalEvent(event: IncomingInternalEvent) {
const { type, payload } = event;

if (type === "crypto-payment:incoming-transaction") {
const { serializedTransaction } = payload;
console.log("[Crossmint] Received incoming transaction", serializedTransaction);
handleIncomingTransaction(serializedTransaction);
}
}

async function handleIncomingTransaction(serializedTransaction: string) {
try {
const txId = await signer.signAndSendTransaction(serializedTransaction);
let txId: string;
switch (paymentMethod) {
case "SOL":
txId = await handleSOLTransaction(signer, serializedTransaction);
break;
case "ETH":
txId = await handleETHTransaction(signer, serializedTransaction);
break;
default:
throw new Error(`Unsupported payment method ${paymentMethod}`);
}

console.log("[Crossmint] Signed and sent transaction", txId);
emitInternalEvent({
Expand All @@ -40,5 +55,23 @@ export default function CryptoEmbeddedCheckoutIFrame(props: CryptoEmbeddedChecko
}
}

async function handleSOLTransaction(signer: SOLEmbeddedCheckoutSigner, serializedTransaction: string) {
// @ts-expect-error - Error becasue we dont use 'module' field in tsconfig, which is expected because we use tsup to compile
const { Transaction } = await import("@solana/web3.js");
const transaction = Transaction.from(bs58.decode(serializedTransaction));
console.log("[Crossmint] Deserialized SOL transaction", transaction);

return await signer.signAndSendTransaction(transaction);
}

async function handleETHTransaction(signer: ETHEmbeddedCheckoutSigner, serializedTransaction: string) {
// @ts-expect-error - Error becasue we dont use 'module' field in tsconfig, which is expected because we use tsup to compile
const { parse: parseTransaction } = await import("@ethersproject/transactions");
const transaction = parseTransaction(serializedTransaction);
console.log("[Crossmint] Deserialized ETH transaction", transaction);

return await signer.signAndSendTransaction(transaction);
}

return <CrossmintEmbeddedCheckoutIFrame onInternalEvent={onInternalEvent} {...props} />;
}
Loading

0 comments on commit b693e8d

Please sign in to comment.