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

Feature/add firo network #584

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
mkdir release
docker run --rm --user "$(id -u):$(id -g)" -v `pwd`:/home:rw enkrypt-build-container /bin/bash -c "yarn build:all"
docker run --rm --user "$(id -u):$(id -g)" -v `pwd`:/home:rw enkrypt-build-container /bin/bash -c "cd packages/extension && yarn build:chrome && yarn zip"
mv packages/extension/dist/release.zip release/enkrypt-chrome-edge-opera-${{ steps.get_release_tag.outputs.VERSION }}.zip
mv packages/extension/dist/release.zip release/enkrypt-chrome-edge-${{ steps.get_release_tag.outputs.VERSION }}.zip
docker run --rm --user "$(id -u):$(id -g)" -v `pwd`:/home:rw enkrypt-build-container /bin/bash -c "cd packages/extension && yarn build:opera && yarn zip"
mv packages/extension/dist/release.zip release/enkrypt-opera-${{ steps.get_release_tag.outputs.VERSION }}.zip
docker run --rm --user "$(id -u):$(id -g)" -v `pwd`:/home:rw enkrypt-build-container /bin/bash -c "cd packages/extension && yarn build:firefox && yarn zip"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -119,3 +119,4 @@ dist

# IDE
.history
.idea
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ Enkrypt is a web3 wallet built from the ground up to support the multi-chain fut
- ZChains
- zkSync
- zkSync Goerli
- Firo
- More coming soon!

Looking to add your project? [Contact us!](https://mewwallet.typeform.com/enkrypt-inquiry?typeform-source=www.enkrypt.com)
Expand Down
10 changes: 10 additions & 0 deletions packages/extension/src/libs/keyring/public-keyring.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,16 @@ class PublicKeyRing {
walletType: WalletType.mnemonic,
isHardware: false,
};
allKeys["TMSnbcpSw9JhteaJqioT2sz2sW1Qhqyf2Q"] = {
address: "TMSnbcpSw9JhteaJqioT2sz2sW1Qhqyf2Q",
basePath: "m/44'/1'/0'/0",
name: "fake firo account #1",
pathIndex: 0,
publicKey: "0x0",
signerType: SignerType.secp256k1btc,
walletType: WalletType.mnemonic,
isHardware: false,
};
allKeys['77hREDDaAiimedtD9bR1JDMgYLW3AA5yPvD91pvrueRp'] = {
address: '77hREDDaAiimedtD9bR1JDMgYLW3AA5yPvD91pvrueRp',
basePath: "m/44'/501'/0'/1",
Expand Down
44 changes: 44 additions & 0 deletions packages/extension/src/libs/spark-handler/callRPC.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import axios from "axios";

const DEFAULT_TIMEOUT = 30000;

const RPC_URLS = {
mainnet: "https://firo-rpc.publicnode.com/",
};

const axiosInstance = axios.create({
timeout: DEFAULT_TIMEOUT,
headers: {
"Content-Type": "application/json",
}
});

export async function callRPC<T = any>(
method: string,
params?: object
): Promise<T> {
try {
const response = await axiosInstance.post(
RPC_URLS['mainnet'],
{
jsonrpc: "1.0",
id: "js-client",
method: method,
params: params ?? [],
},
{
headers: {
"Content-Type": "application/json",
},
}
);

if (!response.data || response.data.result === undefined) {
throw new Error('Invalid RPC response structure');
}
return response.data.result;
} catch (error) {
console.error("RPC Error:", error);
throw error;
}
}
43 changes: 43 additions & 0 deletions packages/extension/src/libs/spark-handler/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { SparkAccount } from "@/ui/action/types/account";
import { callRPC } from "./callRPC";

export async function getSparkState(): Promise<SparkAccount> {
const [allAddresses, sparkBalance] = await Promise.all([
callRPC<Record<number, string>>("getallsparkaddresses"),
callRPC("getsparkbalance"),
]);

return {
defaultAddress: Object.values(allAddresses)?.at(-1) ?? "",
allAddresses: Object.values(allAddresses),
sparkBalance,
};
}
narekpetrosyan marked this conversation as resolved.
Show resolved Hide resolved

export async function generateSparkAddress(): Promise<string> {
const newSparkAddress = await callRPC<string[]>("getnewsparkaddress");
return newSparkAddress[0];
}

export async function sendToSparkAddress(to: string, amount: string) {
return await callRPC<string[]>("mintspark", [
{
[to]: { amount: Number(amount) },
},
]);
}

export async function sendFromSparkAddress(
to: string,
amount: string,
subtractFee = false
): Promise<string> {
return await callRPC<string>("spendspark", [
{
[to]: {
amount: Number(amount),
subtractFee,
},
},
]);
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import haskoinHandler from './providers/haskoin';
import ssHandler from './providers/ss';
export { haskoinHandler, ssHandler };
import firoHandler from "./providers/firo";
export { haskoinHandler, ssHandler, firoHandler };
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import MarketData from "@/libs/market-data";
import { FiroTxType } from "@/providers/bitcoin/types";
import { Activity, ActivityStatus, ActivityType } from "@/types/activity";
import { BaseNetwork } from "@/types/base-network";

export default async (
network: BaseNetwork,
pubkey: string
): Promise<Activity[]> => {
return fetch(
`${network.node}/insight-api-zcoin/txs?address=${network.displayAddress(
pubkey
)}&pageSize=40`
)
.then((res) => res.json())
.then(async (txs: { txs: FiroTxType[] }) => {
if ((txs as any).message) return [];
let tokenPrice = "0";
if (network.coingeckoID) {
const marketData = new MarketData();
await marketData
.getTokenPrice(network.coingeckoID)
.then((mdata) => (tokenPrice = mdata || "0"));
}

const address = network.displayAddress(pubkey);

const cleanedTxs = txs.txs.map((tx) => {
return {
...tx,
vin: tx.vin.filter((vi) => vi.addr),
vout: tx.vout.filter((vo) => vo.scriptPubKey.addresses),
};
});

return cleanedTxs.map((tx) => {
const isIncoming = !tx.vin.find((i) => i.addr === address);

let toAddress = "";
let value = 0;

if (isIncoming) {
const relevantOut = tx.vout.find(
(tx) => tx.scriptPubKey.addresses![0] === address
);
if (relevantOut) {
toAddress = relevantOut.scriptPubKey.addresses![0];
value = Number(relevantOut.value);
}
} else {
const relevantOut = tx.vout.find(
(tx) => tx.scriptPubKey.addresses![0] !== address
);
if (relevantOut) {
toAddress = relevantOut.scriptPubKey.addresses![0];
value = Number(relevantOut.value);
} else {
toAddress = tx.vout[0].scriptPubKey.addresses![0];
value = Number(tx.vout[0].value);
}
}

const act: Activity = {
from: tx.vin?.[0]?.addr,
isIncoming,
network: network.name,
status:
tx.blockheight > 0
? ActivityStatus.success
: ActivityStatus.pending,
timestamp: Number(tx.time) * 1000,
to: toAddress,
token: {
decimals: network.decimals,
icon: network.icon,
name: network.name_long,
symbol: network.currencyName,
coingeckoID: network.coingeckoID,
price: tokenPrice,
},
transactionHash: tx.txid,
type: ActivityType.transaction,
value: (+value * 100000000).toString(),
rawInfo: {
blockNumber: tx.blockheight,
fee: Number(tx?.fees),
inputs: tx.vin.map((input) => ({
address: input.addr,
value: Number(input.value),
})),
outputs: tx.vout.map((output) => ({
address: output.scriptPubKey.addresses![0],
value: Number(output.value),
pkscript: output.scriptPubKey.hex,
})),
transactionHash: tx.txid,
timestamp: Number(tx.time) * 1000,
},
};
return act;
});
})
.catch((error) => {
console.log({ error });
return [];
});
};
Loading