Skip to content

Commit

Permalink
feat: adds new chain abstraction methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ganchoradkov committed Dec 19, 2024
1 parent 2899e74 commit 0399cd4
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 76 deletions.
31 changes: 29 additions & 2 deletions packages/walletkit/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,9 +186,9 @@ export class WalletKit extends IWalletKit {
}
};

public canFulfil: IWalletKit["canFulfil"] = async (params) => {
public prepareFulfilment: IWalletKit["prepareFulfilment"] = async (params) => {
try {
return await this.engine.canFulfil(params);
return await this.engine.prepareFulfilment(params);
} catch (error: any) {
this.logger.error(error.message);
throw error;
Expand All @@ -204,6 +204,33 @@ export class WalletKit extends IWalletKit {
}
};

public estimateFees: IWalletKit["estimateFees"] = async (params) => {
try {
return await this.engine.estimateFees(params);
} catch (error: any) {
this.logger.error(error.message);
throw error;
}
};

public getERC20Balance: IWalletKit["getERC20Balance"] = async (params) => {
try {
return await this.engine.getERC20Balance(params);
} catch (error: any) {
this.logger.error(error.message);
throw error;
}
};

public getFulfilmentDetails: IWalletKit["getFulfilmentDetails"] = async (params) => {
try {
return await this.engine.getFulfilmentDetails(params);
} catch (error: any) {
this.logger.error(error.message);
throw error;
}
};

// ---------- Private ----------------------------------------------- //

private async initialize() {
Expand Down
165 changes: 139 additions & 26 deletions packages/walletkit/src/controllers/chainAbstraction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ import { ChainAbstractionTypes, IChainAbstraction, IWalletKitEngine } from "../t
import { FULFILMENT_STATUS, CAN_FULFIL_STATUS } from "../constants";

export class ChainAbstraction extends IChainAbstraction {
private canFulfilHandler: any;
private prepareFulfilmentHandler: any;
private fulfilmentStatusHandler: any;
private estimateFeesHandler: any;
private getERC20BalanceHandler: any;
private getFulfilmentDetailsHandler: any;

private projectId: string;

constructor(public engine: IWalletKitEngine) {
Expand All @@ -14,46 +18,40 @@ export class ChainAbstraction extends IChainAbstraction {
this.projectId = this.engine.client.core.projectId || "";
}

public canFulfil: IChainAbstraction["canFulfil"] = async (params) => {
console.log("canFulfil", params);
if (!this.canFulfilHandler) {
throw new Error(`canFulfilHandler not found for environment: '${getEnvironment()}'`);
public prepareFulfilment: IChainAbstraction["prepareFulfilment"] = async (params) => {
console.log("prepareFulfilment", params);
if (!this.prepareFulfilmentHandler) {
throw new Error(`prepareFulfilmentHandler not found for environment: '${getEnvironment()}'`);
}

const { transaction } = params;

const result = (await this.canFulfilHandler({
const result = (await this.prepareFulfilmentHandler({
transaction,
projectId: this.projectId,
})) as ChainAbstractionTypes.CanFulfilHandlerResult;
console.log("canFulfil processing result..", result);
})) as ChainAbstractionTypes.PrepareFulfilmentHandlerResult;
console.log("prepareFulfilment processing result..", result);
switch (result.status) {
case CAN_FULFIL_STATUS.error:
return { status: CAN_FULFIL_STATUS.error, reason: result.reason };
case CAN_FULFIL_STATUS.not_required:
return { status: CAN_FULFIL_STATUS.not_required };
case CAN_FULFIL_STATUS.available:
// eslint-disable-next-line no-case-declarations
const routes = result.data.routes;
// eslint-disable-next-line no-case-declarations
const routesDetails = result.data.routesDetails;
const routes = result.data;
return {
status: CAN_FULFIL_STATUS.available,
data: {
routes: {
fulfilmentId: routes.orchestrationId,
checkIn: routes.checkIn,
transactions: routes.transactions,
funding: routes.metadata.fundingFrom,
initialTransaction: routes.initialTransaction,
},
routesDetails: {
totalFees: routesDetails.localTotal,
},
fulfilmentId: routes.orchestrationId,
checkIn: routes.checkIn,
transactions: routes.transactions,
funding: routes.metadata.fundingFrom,
initialTransaction: routes.initialTransaction,
initialTransactionMetadata: routes.metadata.initialTransaction,
},
};
default:
throw new Error(`Invalid canFulfil status: ${JSON.stringify(result)}`);
throw new Error(`Invalid prepareFulfilment status: ${JSON.stringify(result)}`);
}
};

Expand All @@ -77,6 +75,92 @@ export class ChainAbstraction extends IChainAbstraction {
return result;
};

/**
* TODO: pass projectId to yttrium handlers
*/

public estimateFees: IChainAbstraction["estimateFees"] = async (params) => {
if (!this.estimateFeesHandler) {
throw new Error(`estimateFeesHandler not found for environment: '${getEnvironment()}'`);
}
const result = await this.estimateFeesHandler({
...params,
projectId: this.projectId,
});

console.log("estimateFees result", result);
return result;
};

public getERC20Balance: IChainAbstraction["getERC20Balance"] = async (params) => {
if (!this.getERC20BalanceHandler) {
throw new Error(`getERC20BalanceHandler not found for environment: '${getEnvironment()}'`);
}
const result = await this.getERC20BalanceHandler({
...params,
projectId: this.projectId,
});

console.log("getERC20Balance result", result);
return result;
};

public getFulfilmentDetails: IChainAbstraction["getFulfilmentDetails"] = async (params) => {
if (!this.getFulfilmentDetailsHandler) {
throw new Error(
`getFulfilmentDetailsHandler not found for environment: '${getEnvironment()}'`,
);
}
const { fulfilmentId } = params;
const result = await this.getFulfilmentDetailsHandler({
...params,
orchestrationId: fulfilmentId,
projectId: this.projectId,
});

console.log("getFulfilmentDetails handler result", result);
const bridgeDetails: ChainAbstractionTypes.TransactionFee[] = [];

for (const fees of result.bridge) {
bridgeDetails.push({
fee: fees.fee,
localFee: fees.localFee,
});
}

const routeDetails: ChainAbstractionTypes.TransactionDetails[] = [];

for (const transaction of result.route) {
routeDetails.push({
transaction: transaction.transaction,
eip1559: transaction.estimate,
transactionFee: transaction.fee,
});
}

const initialTransactionDetails: ChainAbstractionTypes.TransactionDetails = {
transaction: result.initial.transaction,
eip1559: result.initial.estimate,
transactionFee: result.initial.fee,
};

const totalFee: ChainAbstractionTypes.TotalFee = result.localTotal;

console.log("getFulfilmentDetails parsed result", {
routeDetails,
initialTransactionDetails,
bridgeDetails,
totalFee,
});

return {
routeDetails,
initialTransactionDetails,
bridgeDetails,
totalFee,
};
};

private loadHandlers = () => {
const env = getEnvironment();
switch (env) {
Expand All @@ -95,8 +179,16 @@ export class ChainAbstraction extends IChainAbstraction {
console.warn("React Native Yttrium not found in global scope");
return;
}
this.canFulfilHandler = yttrium.checkRoute;
this.fulfilmentStatusHandler = yttrium.checkStatus;
this.prepareFulfilmentHandler = async (params: any) =>
this.parseResult(await yttrium.prepare(params));
this.fulfilmentStatusHandler = async (params: any) =>
this.parseResult(await yttrium.status(params));
this.estimateFeesHandler = async (params: any) =>
this.parseResult(await yttrium.estimateFees(params));
this.getERC20BalanceHandler = async (params: any) =>
this.parseResult(await yttrium.getERC20Balance(params));
this.getFulfilmentDetailsHandler = async (params: any) =>
this.parseResult(await yttrium.getBridgeDetails(params));
};

private Browser = () => {
Expand All @@ -108,7 +200,28 @@ export class ChainAbstraction extends IChainAbstraction {
if (!yttrium) {
console.warn("Yttrium not available in node environment");
}
this.canFulfilHandler = yttrium.checkRoute;
this.fulfilmentStatusHandler = yttrium.checkStatus;

this.prepareFulfilmentHandler = async (params: any) =>
this.parseResult(await yttrium.prepare(params));
this.fulfilmentStatusHandler = async (params: any) =>
this.parseResult(await yttrium.status(params));
this.estimateFeesHandler = async (params: any) =>
this.parseResult(await yttrium.estimateFees(params));
this.getERC20BalanceHandler = async (params: any) =>
this.parseResult(await yttrium.getERC20Balance(params));
this.getFulfilmentDetailsHandler = async (params: any) =>
this.parseResult(await yttrium.getBridgeDetails(params));
};

private parseResult = (result: any) => {
if (typeof result === "undefined") return;

// iOS returns parsed JSON object, while Android returns stringified
if (typeof result === "string") {
try {
return JSON.parse(result);
} catch (e) {}
}
return result;
};
}
17 changes: 15 additions & 2 deletions packages/walletkit/src/controllers/engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,26 @@ export class Engine extends IWalletKitEngine {
};

// Chain Abstraction //
public canFulfil: IWalletKitEngine["canFulfil"] = async (params) => {
return await this.chainAbstraction.canFulfil(params);
public prepareFulfilment: IWalletKitEngine["prepareFulfilment"] = async (params) => {
return await this.chainAbstraction.prepareFulfilment(params);
};

public fulfilmentStatus: IWalletKitEngine["fulfilmentStatus"] = async (params) => {
return await this.chainAbstraction.fulfilmentStatus(params);
};

public estimateFees: IWalletKitEngine["estimateFees"] = async (params) => {
return await this.chainAbstraction.estimateFees(params);
};

public getERC20Balance: IWalletKitEngine["getERC20Balance"] = async (params) => {
return await this.chainAbstraction.getERC20Balance(params);
};

public getFulfilmentDetails: IWalletKitEngine["getFulfilmentDetails"] = async (params) => {
return await this.chainAbstraction.getFulfilmentDetails(params);
};

// ---------- Private ----------------------------------------------- //

private onSessionRequest = (event: WalletKitTypes.SessionRequest) => {
Expand Down
Loading

0 comments on commit 0399cd4

Please sign in to comment.