Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
f3dde22
devop: merge
kvhnuke Dec 13, 2024
0d16daa
feature: add firo network spark address generation and vew functional…
narekpetrosyan Dec 10, 2024
e36e2d3
feature: add transparent -> spark address fund sending functionality
narekpetrosyan Dec 16, 2024
643b114
feature: add send from spark to spark address functionality
narekpetrosyan Dec 24, 2024
ce6ed47
[WIP]: add wasm handler
narekpetrosyan Feb 27, 2025
e9ad83c
fix balance preview for Firo chain, add anonymize funds functionality
narekpetrosyan Mar 31, 2025
51d3fef
add socket electrumx client interactions
narekpetrosyan Apr 18, 2025
1820efd
added TODO for loading wasm in worker
narekpetrosyan Apr 22, 2025
e64272b
PK remaining
narekpetrosyan May 6, 2025
12d8523
PK fix errors
narekpetrosyan May 8, 2025
ad52556
add DB sync for metas, fix wasm script loading 2 times
narekpetrosyan May 14, 2025
20037b4
change wasm to modularized
narekpetrosyan May 16, 2025
e3199ce
fix coin processing
narekpetrosyan May 16, 2025
ad77bac
save processed coin value sum in DB
narekpetrosyan May 16, 2025
37f89c8
spark balance calculation
narekpetrosyan May 20, 2025
6fa0e37
refactor: fix append data
narekpetrosyan May 23, 2025
140167e
crate hardcoded txData
VahanSargsyan Aug 19, 2025
1f54a66
add spark tx
VahanSargsyan Oct 24, 2025
b1376b0
add get coins tags methods
VahanSargsyan Oct 29, 2025
47dd4ff
Fix spark send and public send actions: FIRO
narekpetrosyan Nov 3, 2025
1e23aaf
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Nov 3, 2025
f6970bf
Add TX activity history after sending from Spark address
narekpetrosyan Nov 5, 2025
b78b5cf
Merge pull request #1 from firoorg/feature/from-spark-tx-activity
narekpetrosyan Nov 6, 2025
9853950
Disable activity when spark to spark transaction is failed or dropped
narekpetrosyan Nov 9, 2025
62217a9
add coin tags handling
VahanSargsyan Nov 10, 2025
92a5520
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Nov 10, 2025
ad138ff
Merge pull request #2 from firoorg/feature/disable-activity-when-fail…
narekpetrosyan Nov 15, 2025
9569d29
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Nov 15, 2025
166e5af
add coins set sync handler
VahanSargsyan Nov 15, 2025
c8b7129
Minor changes
narekpetrosyan Nov 16, 2025
b1de5db
move tags update to sync
VahanSargsyan Nov 19, 2025
5f01994
move tags update to sync
VahanSargsyan Nov 22, 2025
1489fa3
Add synchronization logic for sets and tags
narekpetrosyan Nov 23, 2025
a4956f7
Merge pull request #3 from firoorg/feature/sync-tags-and-sets
narekpetrosyan Nov 24, 2025
ddebcf0
Add synchronization logic for sets and tags
narekpetrosyan Nov 25, 2025
47be2db
Fix tags append issue, fix coin calculation issue
narekpetrosyan Nov 26, 2025
716490d
Merge pull request #4 from firoorg/feature/spark-balance-calculation
narekpetrosyan Nov 27, 2025
da156e6
Add spark address generation
narekpetrosyan Dec 1, 2025
6ee1c2e
Move all axios calls to electrum
narekpetrosyan Dec 2, 2025
03a9e7f
fix spark tx
VahanSargsyan Nov 30, 2025
45ced19
Merge pull request #5 from firoorg/feature/spark-address-generation
narekpetrosyan Dec 5, 2025
f12af42
Minor fix
narekpetrosyan Dec 9, 2025
8e9a2cd
Fix transparent to transparent transaction
narekpetrosyan Dec 10, 2025
642e421
fix merge conflicts
narekpetrosyan Dec 10, 2025
178e17a
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Dec 10, 2025
0b598b0
Minor fix
narekpetrosyan Dec 14, 2025
9f1d697
fix UI new tab button
VahanSargsyan Dec 14, 2025
db4b702
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Dec 14, 2025
c95f159
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Dec 14, 2025
c867060
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Dec 15, 2025
3d278fb
fix tests
VahanSargsyan Dec 16, 2025
26d3189
Fix Vue warnings
narekpetrosyan Dec 16, 2025
66af092
Merge remote-tracking branch 'origin/feature/add-firo-network' into f…
narekpetrosyan Dec 16, 2025
4cda38c
Fix activity view and confirm send to spark transaction view
narekpetrosyan Dec 17, 2025
ae7a1d9
Fix activity view and confirm send to spark transaction view
narekpetrosyan Dec 17, 2025
0206ae7
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Dec 17, 2025
ca09ac0
hide spark send tabs
VahanSargsyan Dec 18, 2025
33bc01c
Merge branch 'develop' into feature/add-firo-network
VahanSargsyan Dec 18, 2025
cdca95c
hide Full Screen button
VahanSargsyan Dec 18, 2025
4e667a5
coderabbit suggestions
narekpetrosyan Dec 23, 2025
6941111
Add _free memory executions for generateSparkWallet
narekpetrosyan Dec 23, 2025
35d8e3d
Clean up allocated memory in generateSparkWallet
narekpetrosyan Dec 23, 2025
49e5b62
Fix
narekpetrosyan Dec 23, 2025
42e1c8c
Fix free memory
narekpetrosyan Dec 23, 2025
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
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 @@ -121,6 +121,7 @@ Enkrypt is a web3 wallet built from the ground up to support the multi-chain fut
- Unit Zero Testnet
- Nibiru
- Nibiru Testnet
- Firo
- More coming soon!

Looking to add your project? [Contact us!](https://mewwallet.typeform.com/enkrypt-inquiry?typeform-source=www.enkrypt.com)
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,8 @@
"@ledgerhq/speculos-transport": "https://registry.yarnpkg.com/@favware/skip-dependency/-/skip-dependency-1.2.1.tgz",
"@ledgerhq/ledger-key-ring-protocol": "https://registry.yarnpkg.com/@favware/skip-dependency/-/skip-dependency-1.2.1.tgz",
"@amplitude/plugin-autocapture-browser@^1.0.2": "patch:@amplitude/plugin-autocapture-browser@npm%3A1.0.3#./.yarn/patches/@amplitude-plugin-autocapture-browser-npm-1.0.3-edb25bef55.patch"
},
"dependencies": {
"ecpair": "3.0.0-rc.0"
}
}
2 changes: 2 additions & 0 deletions packages/extension/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
**/*.js
**/*.d.ts
3 changes: 3 additions & 0 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
},
"dependencies": {
"@amplitude/analytics-browser": "^2.32.0",
"@bitcoinerlab/secp256k1": "^1.2.0",
"@enkryptcom/extension-bridge": "workspace:^",
"@enkryptcom/hw-wallets": "workspace:^",
"@enkryptcom/keyring": "workspace:^",
Expand Down Expand Up @@ -65,6 +66,8 @@
"bs58": "^6.0.0",
"concurrently": "^9.2.1",
"echarts": "^6.0.0",
"ecpair": "^3.0.0",
"electrum-client-browser": "1.2.5",
"ethereum-cryptography": "^2.2.1",
"ethereumjs-abi": "^0.6.8",
"eventemitter3": "^5.0.1",
Expand Down
30 changes: 18 additions & 12 deletions packages/extension/src/libs/background/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import DomainState from '@/libs/domain-state';
import { sendToWindow } from '@/libs/messenger/extension';
import PersistentEvents from '@/libs/persistent-events';
import TabInfo from '@/libs/utils/tab-info';
import Providers from '@/providers';
import { BaseFiroWallet } from '@/providers/bitcoin/libs/firo-wallet/base-firo-wallet';
import {
InternalMethods,
InternalOnMessageResponse,
Message,
} from '@/types/messenger';
import { RPCRequestType, OnMessageResponse } from '@enkryptcom/types';
import { ProviderName } from '@/types/provider';
import { OnMessageResponse, RPCRequestType } from '@enkryptcom/types';
import { v4 as randomUUID } from 'uuid';
import Browser from 'webextension-polyfill';
import { getCustomError } from '../error';
import KeyRingBase from '../keyring/keyring';
import { sendToWindow } from '@/libs/messenger/extension';
import { ProviderName } from '@/types/provider';
import Providers from '@/providers';
import Browser from 'webextension-polyfill';
import TabInfo from '@/libs/utils/tab-info';
import PersistentEvents from '@/libs/persistent-events';
import DomainState from '@/libs/domain-state';
import { TabProviderType, ProviderType, ExternalMessageOptions } from './types';
import { getProviderNetworkByName } from '../utils/networks';
import {
sign,
getEthereumPubKey,
ethereumDecrypt,
getEthereumPubKey,
sign,
unlock,
changeNetwork,
sendToTab,
Expand All @@ -29,9 +29,11 @@ import {
import { handlePersistentEvents } from './external';
import SettingsState from '../settings-state';
import { isGeoRestricted } from '../utils/screening';
import { ExternalMessageOptions, ProviderType, TabProviderType } from './types';

class BackgroundHandler {
#keyring: KeyRingBase;
#wallet: BaseFiroWallet;
#tabProviders: TabProviderType;
#providers: ProviderType;
#persistentEvents: PersistentEvents;
Expand All @@ -41,6 +43,7 @@ class BackgroundHandler {

constructor() {
this.#keyring = new KeyRingBase();
this.#wallet = new BaseFiroWallet();
this.#persistentEvents = new PersistentEvents();
this.#domainState = new DomainState();
this.#settingsState = new SettingsState();
Expand Down Expand Up @@ -162,7 +165,7 @@ class BackgroundHandler {
return response;
});
}
internalHandler(msg: Message): Promise<InternalOnMessageResponse> {
async internalHandler(msg: Message): Promise<InternalOnMessageResponse> {
const message = JSON.parse(msg.message) as RPCRequestType;
switch (message.method) {
case InternalMethods.sign:
Expand All @@ -172,6 +175,9 @@ class BackgroundHandler {
case InternalMethods.ethereumDecrypt:
return ethereumDecrypt(this.#keyring, message);
case InternalMethods.unlock:
const password = message?.params?.[0] as string;
const mnemonic = await this.#keyring.getSavedMnemonic(password);
this.#wallet.setSecret(mnemonic);
return unlock(this.#keyring, message);
case InternalMethods.lock:
return lock(this.#keyring);
Expand Down
10 changes: 8 additions & 2 deletions packages/extension/src/libs/keyring/keyring.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import KeyRing from '@enkryptcom/keyring';
import { InternalStorageNamespace } from '@/types/provider';
import BrowserStorage from '../common/browser-storage';
import KeyRing from '@enkryptcom/keyring';
import {
EnkryptAccount,
HWWalletAdd,
Expand All @@ -11,6 +10,7 @@ import {
SignOptions,
WalletType,
} from '@enkryptcom/types';
import BrowserStorage from '../common/browser-storage';
export class KeyRingBase {
#keyring: KeyRing;
constructor() {
Expand Down Expand Up @@ -70,6 +70,12 @@ export class KeyRingBase {
getKeysObject(): Promise<{ [key: string]: EnkryptAccount }> {
return this.#keyring.getKeysObject();
}
getPrivateKey(seed: Buffer) {
return this.#keyring.getPrivateKey(seed);
}
getSavedMnemonic(password: string) {
return this.#keyring.getSavedMnemonic(password);
}
addHWAccount(account: HWWalletAdd): Promise<EnkryptAccount> {
return this.#keyring.addHWAccount(account);
}
Expand Down
13 changes: 11 additions & 2 deletions packages/extension/src/libs/keyring/public-keyring.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {
SignerType,
EnkryptAccount,
Errors,
SignerType,
SignOptions,
WalletType,
EnkryptAccount,
} from '@enkryptcom/types';
import { KeyRingBase } from './keyring';

Expand Down Expand Up @@ -145,5 +146,13 @@ class PublicKeyRing {

return alreadyExists;
}

async getPrivateKey(seed: Buffer) {
return this.#keyring.getPrivateKey(seed);
}

getSavedMnemonic(password: string) {
return this.#keyring.getSavedMnemonic(password);
}
}
export default PublicKeyRing;
3 changes: 3 additions & 0 deletions packages/extension/src/libs/spark-handler/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export const SPARK_TX_TYPE = 9;

export const LOCK_TIME = 999999;
39 changes: 39 additions & 0 deletions packages/extension/src/libs/spark-handler/createTempFromSparkTx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as bitcoin from 'bitcoinjs-lib';
import { LOCK_TIME, SPARK_TX_TYPE } from '@/libs/spark-handler/constants';
import { isSparkAddress } from '@/providers/bitcoin/libs/utils';

interface CreateTempFromSparkTxArgs {
network: bitcoin.networks.Network;
to: string;
amount: string;
}

// TODO: please check do we need all this temTx stuff if we only using **txHashSig**

export const createTempFromSparkTx = async ({
network,
amount,
to,
}: CreateTempFromSparkTxArgs): Promise<string> => {
const isSparkTransaction = await isSparkAddress(to);

const tempTx = new bitcoin.Psbt({ network });
tempTx.setVersion(3 | (SPARK_TX_TYPE << 16)); // version 3 and tx type in high bits (3 | (SPARK_TX_TYPE << 16));
tempTx.setLocktime(LOCK_TIME); // new Date().getTime() / 1000

tempTx.addInput({
hash: '0000000000000000000000000000000000000000000000000000000000000000',
index: 4294967295,
sequence: 4294967295,
finalScriptSig: Buffer.from('d3', 'hex'),
});

const tempTxBuffer = tempTx.extractTransaction(true).toBuffer();
const extendedTempTxBuffer = Buffer.concat([
tempTxBuffer,
Buffer.from([0x00]),
]);

const txHash = bitcoin.crypto.hash256(extendedTempTxBuffer);
return txHash.reverse().toString('hex');
};
79 changes: 79 additions & 0 deletions packages/extension/src/libs/spark-handler/createTempTx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { validator } from '@/providers/bitcoin/libs/firo-wallet/firo-wallet';
import BigNumber from 'bignumber.js';
import * as bitcoin from 'bitcoinjs-lib';
import { ECPairInterface } from 'ecpair';

interface CreateTempTxArgs {
network: bitcoin.networks.Network;
changeAmount: BigNumber;
mintValueOutput: {
script: Buffer<ArrayBuffer>;
value: number;
}[];
inputs: {
hash: string;
index: number;
nonWitnessUtxo: Buffer<ArrayBuffer>;
}[];
spendableUtxos: {
keyPair: ECPairInterface;
address: string;
txid: string;
vout: number;
scriptPubKey: string;
amount: number;
satoshis: number;
confirmations: number;
}[];
addressKeyPairs: Record<string, any>;
}

export const createTempTx = ({
network,
inputs,
spendableUtxos,
addressKeyPairs,
mintValueOutput,
changeAmount,
}: CreateTempTxArgs) => {
const tx = new bitcoin.Psbt({ network });
tx.setVersion(2);

inputs.forEach(input => {
tx.addInput(input);
});

mintValueOutput.forEach(mint => {
tx.addOutput({
script: mint.script,
value: mint.value,
});
});

if (changeAmount.gt(0)) {
const firstUtxoAddress = spendableUtxos[0].address;

tx.addOutput({
address: firstUtxoAddress!,
value: changeAmount.toNumber(),
});
}

for (let index = 0; index < spendableUtxos.length; index++) {
const utxo = spendableUtxos[index];
const keyPair = addressKeyPairs[utxo.address];

const Signer = {
sign: (hash: Uint8Array) => {
return Buffer.from(keyPair.sign(hash));
},
publicKey: Buffer.from(keyPair.publicKey),
} as unknown as bitcoin.Signer;

tx.signInput(index, Signer);
}
tx.validateSignaturesOfAllInputs(validator);
tx.finalizeAllInputs();

return tx.extractTransaction();
};
Loading