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

Feat: elrond family integration #133

Merged
merged 13 commits into from
Apr 4, 2023
Merged
6 changes: 6 additions & 0 deletions .changeset/nine-dingos-prove.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@ledgerhq/wallet-api-core": minor
"wallet-api-website": minor
---

support elrond family
1 change: 1 addition & 0 deletions packages/core/src/families/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const FAMILIES = [
"tron",
"near",
"neo",
"elrond",
] as const;

export const schemaFamilies = z.enum(FAMILIES);
42 changes: 42 additions & 0 deletions packages/core/src/families/elrond/serializer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import BigNumber from "bignumber.js";
import type { ElrondTransaction, RawElrondTransaction } from "./types";

export function serializeElrondTransaction({
amount,
data,
family,
fees,
gasLimit,
RamyEB marked this conversation as resolved.
Show resolved Hide resolved
mode,
recipient,
}: ElrondTransaction): RawElrondTransaction {
return {
family,
amount: amount.toString(),
recipient,
mode,
fees: fees ? fees.toString() : undefined,
data,
gasLimit,
};
}

export function deserializeElrondTransaction({
amount,
data,
family,
fees,
gasLimit,
mode,
recipient,
}: RawElrondTransaction): ElrondTransaction {
return {
family,
mode,
amount: new BigNumber(amount),
recipient,
fees: fees ? new BigNumber(fees) : undefined,
data,
gasLimit,
};
}
17 changes: 17 additions & 0 deletions packages/core/src/families/elrond/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type BigNumber from "bignumber.js";
import type { z } from "zod";
import type { TransactionCommon } from "../index";
import type {
schemaRawElrondTransaction,
ElrondOperationMode,
} from "./validation";

export interface ElrondTransaction extends TransactionCommon {
readonly family: RawElrondTransaction["family"];
mode: ElrondOperationMode;
data?: string;
fees?: BigNumber;
gasLimit: number;
}

export type RawElrondTransaction = z.infer<typeof schemaRawElrondTransaction>;
28 changes: 28 additions & 0 deletions packages/core/src/families/elrond/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { z } from "zod";
import { schemaFamilies, schemaTransactionCommon } from "../common";

export const schemaOperationMode = z.enum([
"send",
"delegate",
"reDelegateRewards",
"unDelegate",
"claimRewards",
"withdraw",
]);

export type ElrondOperationMode = z.infer<typeof schemaOperationMode>;

export const schemaRawElrondTransaction = schemaTransactionCommon.extend({
family: z.literal(schemaFamilies.enum.elrond),
mode: z.union([
z.literal("send"),
z.literal("delegate"),
z.literal("reDelegateRewards"),
z.literal("unDelegate"),
z.literal("claimRewards"),
z.literal("withdraw"),
]),
fees: z.string().optional(),
data: z.string().optional(),
gasLimit: z.number(),
});
2 changes: 1 addition & 1 deletion packages/core/src/families/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export * from "./ripple/types";
export * from "./stellar/types";
export * from "./tezos/types";
export * from "./tron/types";

export * from "./elrond/types";
export * from "./common";
export * from "./serializer";
export * from "./types";
Expand Down
8 changes: 8 additions & 0 deletions packages/core/src/families/serializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ import {
deserializeTronTransaction,
serializeTronTransaction,
} from "./tron/serializer";
import {
deserializeElrondTransaction,
serializeElrondTransaction,
} from "./elrond/serializer";

import type { RawTransaction, Transaction } from "./types";

Expand Down Expand Up @@ -94,6 +98,8 @@ export function serializeTransaction(transaction: Transaction): RawTransaction {
return near.serialize(transaction);
case "neo":
return neo.serialize(transaction);
case "elrond":
return serializeElrondTransaction(transaction);
default: {
const exhaustiveCheck: never = transaction; // https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
return exhaustiveCheck;
Expand Down Expand Up @@ -143,6 +149,8 @@ export function deserializeTransaction(
return near.deserialize(rawTransaction);
case "neo":
return neo.deserialize(rawTransaction);
case "elrond":
return deserializeElrondTransaction(rawTransaction);
default: {
const exhaustiveCheck: never = rawTransaction; // https://www.typescriptlang.org/docs/handbook/2/narrowing.html#exhaustiveness-checking
return exhaustiveCheck;
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/families/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type { RippleTransaction } from "./ripple/types";
import type { StellarTransaction } from "./stellar/types";
import type { TezosTransaction } from "./tezos/types";
import type { TronTransaction } from "./tron/types";
import type { ElrondTransaction } from "./elrond/types";
import type { schemaRawTransaction } from "./validation";

/**
Expand Down Expand Up @@ -73,4 +74,5 @@ export type Transaction =
| StellarTransaction
| TronTransaction
| NearTransaction
| NeoTransaction;
| NeoTransaction
| ElrondTransaction;
2 changes: 2 additions & 0 deletions packages/core/src/families/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { schemaRawTezosTransaction } from "./tezos/validation";
import { schemaRawTronTransaction } from "./tron/validation";
import { schemaRawHederaTransaction } from "./hedera/validation";
import { schemaRawFilecoinTransaction } from "./filecoin/validation";
import { schemaRawElrondTransaction } from "./elrond/validation";

export const schemaRawTransaction = z.discriminatedUnion("family", [
schemaRawAlgorandTransaction,
Expand All @@ -31,4 +32,5 @@ export const schemaRawTransaction = z.discriminatedUnion("family", [
schemaRawStellarTransaction,
schemaRawTezosTransaction,
schemaRawTronTransaction,
schemaRawElrondTransaction,
]);
100 changes: 100 additions & 0 deletions packages/core/tests/serializers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import {
RawNeoTransaction,
NearTransaction,
NeoTransaction,
ElrondTransaction,
RawElrondTransaction,
} from "../src";

const date = new Date();
Expand Down Expand Up @@ -576,6 +578,54 @@ describe("serializers.ts", () => {
});
});
});

describe("elrond", () => {
const family = schemaFamilies.enum.elrond;

it("should serialize an Elrond transaction with data and fees", () => {
const transaction: ElrondTransaction = {
amount: new BigNumber(100),
data: "test",
family,
fees: new BigNumber(100),
mode: "send",
recipient: "recipient",
gasLimit: 0,
};
const serializedTransaction = serializeTransaction(transaction);

expect(serializedTransaction).toEqual({
amount: "100",
data: "test",
gasLimit: 0,
family,
fees: "100",
mode: "send",
recipient: "recipient",
});
});

it("should serialize an Elrond transaction without data and fees", () => {
const transaction: ElrondTransaction = {
amount: new BigNumber(100),
family,
mode: "send",
recipient: "recipient",
gasLimit: 0,
};
const serializedTransaction = serializeTransaction(transaction);

expect(serializedTransaction).toEqual({
amount: "100",
data: undefined,
gasLimit: 0,
family,
fees: undefined,
mode: "send",
recipient: "recipient",
});
});
});
});

describe("deserializeTransaction", () => {
Expand Down Expand Up @@ -1085,6 +1135,56 @@ describe("serializers.ts", () => {
});
});
});

describe("elrond", () => {
const family = schemaFamilies.enum.elrond;

it("should serialize an Elrond transaction with data and fees", () => {
const serializedTransaction: RawElrondTransaction = {
amount: "100",
data: "test",
family,
fees: "100",
mode: "send",
recipient: "recipient",
gasLimit: 0,
};

const transaction = deserializeTransaction(serializedTransaction);

expect(transaction).toEqual({
amount: new BigNumber(100),
data: "test",
family,
fees: new BigNumber(100),
mode: "send",
recipient: "recipient",
gasLimit: 0,
});
});

it("should serialize an Elrond transaction without data and fees", () => {
const serializedTransaction: RawElrondTransaction = {
amount: "100",
family,
mode: "send",
recipient: "recipient",
gasLimit: 0,
};

const transaction = deserializeTransaction(serializedTransaction);

expect(transaction).toEqual({
amount: new BigNumber(100),
data: undefined,
family,
fees: undefined,
mode: "send",
recipient: "recipient",
gasLimit: 0,
});
});
});
});

describe("Serialize -> Deserialize flow", () => {
Expand Down