Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
113 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
60368ac
fix: error that occurred when executing two Spark transactions in a row.
VahanSargsyan Jan 14, 2026
83e0a62
feat: get mint and spend activities from tags and hashes.
VahanSargsyan Jan 29, 2026
117e432
Fix processing modal appearance, refactor sendAction in send from spa…
narekpetrosyan Jan 29, 2026
835763c
Merge pull request #7 from firoorg/fix/modal-appearance
VahanSargsyan Jan 30, 2026
3a20136
Fix activities appearance and saving in activity state
narekpetrosyan Jan 31, 2026
aa4848f
fix: bulk coins status write in db
VahanSargsyan Feb 1, 2026
06eb5de
Merge pull request #8 from firoorg/fix/show-activity
narekpetrosyan Feb 1, 2026
86fa8c5
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Feb 1, 2026
4743d5d
fix: coin check functionality
VahanSargsyan Feb 3, 2026
dc23193
fix: anonymitySet sector getting bug
VahanSargsyan Feb 6, 2026
1ef2261
Save last found coin set id in DB
narekpetrosyan Feb 1, 2026
f7c344e
Remove coin info worker manipulations
narekpetrosyan Feb 3, 2026
be3abd6
Add coin synchronizing
narekpetrosyan Feb 8, 2026
7a4204a
Add coin synchronizing with modal and separate states
narekpetrosyan Feb 8, 2026
72bfcbd
Merge pull request #9 from firoorg/lastcoinsetid-into-db
narekpetrosyan Feb 8, 2026
2a703d2
fix: anonymity set update order
VahanSargsyan Feb 9, 2026
71862d1
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Feb 9, 2026
ff912c9
Fix get balance
narekpetrosyan Feb 8, 2026
002012d
Add anonymize functionality
narekpetrosyan Feb 9, 2026
bfcda3a
fix: anonymity set update order
VahanSargsyan Feb 10, 2026
f042e1d
Merge pull request #10 from firoorg/fix/fix-prod-bugs
VahanSargsyan Feb 10, 2026
b6bb483
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Feb 10, 2026
39f9494
Revert "Fix get balance"
narekpetrosyan Feb 10, 2026
237a55f
add: value to received spark transaction activity
VahanSargsyan Feb 10, 2026
d8c955b
Minor changes
narekpetrosyan Feb 10, 2026
65ba42f
Merge branch 'feature/add-firo-network' into revert-10-fix/fix-prod-bugs
narekpetrosyan Feb 10, 2026
0e923d6
Merge pull request #11 from firoorg/revert-10-fix/fix-prod-bugs
narekpetrosyan Feb 10, 2026
2a128df
Fix activity state and add reset DB on reset
narekpetrosyan Feb 11, 2026
d6b4e08
Merge pull request #12 from firoorg/feature/fix-activity-state
VahanSargsyan Feb 12, 2026
208cd42
fix: private balance check on new wallets
VahanSargsyan Feb 12, 2026
db6d501
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Feb 12, 2026
913dba8
feat: filter firo accounts
VahanSargsyan Feb 17, 2026
0c5cac2
Show compatible accounts on Firo, show only spark addresses
narekpetrosyan Feb 17, 2026
ab10fd5
fix: firo accounts filtering
VahanSargsyan Feb 19, 2026
188dfd2
1. Accounts list show spark addresses
narekpetrosyan Feb 19, 2026
418048f
Remove redundant code, show inactive accounts addresses
narekpetrosyan Feb 23, 2026
138662e
Merge pull request #13 from firoorg/bugfix/test-bugs
narekpetrosyan Feb 23, 2026
5396d08
Fix sending from spark spend utxo
narekpetrosyan Mar 7, 2026
339884d
fix: spark to transparent transaction
VahanSargsyan Mar 16, 2026
4bc47c8
Minor fix
narekpetrosyan Mar 17, 2026
6828efa
Merge remote-tracking branch 'firo/feature/add-firo-network' into fea…
VahanSargsyan Mar 17, 2026
0e58ba0
Fix activity state value representation
narekpetrosyan Mar 18, 2026
270c141
Optimize coin updates and balance calculation logics
VahanSargsyan Mar 30, 2026
1362fcf
Merge pull request #794 from enkryptcom/develop
kvhnuke Apr 13, 2026
fc944d4
Fix data inconsistency issue
narekpetrosyan Apr 16, 2026
258de8e
Fix merge conflicts with main
narekpetrosyan Apr 16, 2026
f641bb5
Fix test cases
narekpetrosyan Apr 22, 2026
c06b438
Free WASM pointers in getMintTxData and getSparkCoinInfo
narekpetrosyan Apr 22, 2026
954bb4b
fix(spark): allocate WASM buffer for serialContext using its own length
cursoragent Apr 23, 2026
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
4 changes: 4 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.38.1",
"@bitcoinerlab/secp256k1": "^1.2.0",
"@enkryptcom/extension-bridge": "workspace:^",
"@enkryptcom/hw-wallets": "workspace:^",
"@enkryptcom/keyring": "workspace:^",
Expand Down Expand Up @@ -62,9 +63,12 @@
"bignumber.js": "^9.3.1",
"bip39": "^3.1.0",
"bitcoinjs-lib": "^6.1.7",
"bitcoinjs-lib-firo": "git+https://github.com/blockstars-tech/bitcoinjs-lib#4b0c4322cb9f308cb84b2f655d16a9e9abc7b4e1",
"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.4",
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
23 changes: 21 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 @@ -105,6 +106,16 @@ class PublicKeyRing {
isHardware: false,
isTestWallet: true,
};
allKeys['TMSnbcpSw9JhteaJqioT2sz2sW1Qhqyf2Q'] = {
address: 'TMSnbcpSw9JhteaJqioT2sz2sW1Qhqyf2Q',
basePath: "m/44'/136'/0'/0",
name: 'firo account',
pathIndex: 0,
publicKey: '0x0',
signerType: SignerType.secp256k1btc,
walletType: WalletType.mnemonic,
isHardware: false,
};
}
return allKeys;
}
Expand Down Expand Up @@ -145,5 +156,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;
53 changes: 53 additions & 0 deletions packages/extension/src/libs/spark-handler/createTempFromSparkTx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as bitcoin from 'bitcoinjs-lib';
import { LOCK_TIME, SPARK_TX_TYPE } from '@/libs/spark-handler/constants';
import { isSparkAddress } from '@/providers/bitcoin/libs/utils';
import BigNumber from 'bignumber.js';

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

interface CreateTempFromSparkTxResult {
txHashSig: string;
additionalTxSize: number;
}

export const createTempFromSparkTx = async ({
network,
amount,
to,
}: CreateTempFromSparkTxArgs): Promise<CreateTempFromSparkTxResult> => {
const isSparkTransaction = await isSparkAddress(to);
const tempTx = new bitcoin.Transaction();
tempTx.version = 3 | (SPARK_TX_TYPE << 16);
tempTx.locktime = LOCK_TIME;
tempTx.addInput(
Buffer.alloc(32, 0),
4294967295,
4294967295,
Buffer.from('d3', 'hex'),
);

const baseTempTxBuffer = tempTx.toBuffer();

if (!isSparkTransaction) {
tempTx.addOutput(
bitcoin.address.toOutputScript(to, network),
new BigNumber(amount).multipliedBy(10 ** 8).toNumber(),
);
}

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

const txHash = bitcoin.crypto.hash256(extendedTempTxBuffer);
return {
txHashSig: txHash.reverse().toString('hex'),
additionalTxSize: fullTempTxBuffer.length - baseTempTxBuffer.length,
};
};
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/base-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 && 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);
}
Comment on lines +62 to +74
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Signing loop assumes inputs and spendableUtxos are 1:1 aligned — no guard.

The loop iterates over spendableUtxos indices and calls tx.signInput(index, ...), but inputs are added from the separate inputs array. If inputs.length !== spendableUtxos.length, this will sign wrong indices or throw at runtime. Additionally, addressKeyPairs[utxo.address] can be undefined, causing an NPE on keyPair.sign.

Proposed fix — add guards
   for (let index = 0; index < spendableUtxos.length; index++) {
     const utxo = spendableUtxos[index];
     const keyPair = addressKeyPairs[utxo.address];
+    if (!keyPair) {
+      throw new Error(`Missing key pair for address: ${utxo.address}`);
+    }
 
     const Signer = {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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);
}
for (let index = 0; index < spendableUtxos.length; index++) {
const utxo = spendableUtxos[index];
const keyPair = addressKeyPairs[utxo.address];
if (!keyPair) {
throw new Error(`Missing key pair for address: ${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);
}
🤖 Prompt for AI Agents
In `@packages/extension/src/libs/spark-handler/createTempTx.ts` around lines 62 -
74, The signing loop assumes spendableUtxos and inputs are aligned and that
addressKeyPairs[utxo.address] exists; update the code to iterate over the actual
inputs array (or explicitly validate lengths) and locate the matching utxo for
each input (e.g., by matching txid/vout or maintaining the same mapping used
when building inputs) before calling tx.signInput(index, ...). Add a guard to
check that the found utxo is defined and that addressKeyPairs[utxo.address]
returns a keyPair; if missing, throw or return a clear error instead of calling
keyPair.sign, and only call tx.signInput with the correct input index and a
Signer built from the validated keyPair.

tx.validateSignaturesOfAllInputs(validator);
tx.finalizeAllInputs();

return tx.extractTransaction();
};
Loading