@sidhujag/sysweb3-keyring 1.0.626 → 1.0.628
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/cjs/keyring-core.js +2512 -0
- package/cjs/keyring-core.js.map +1 -0
- package/cjs/keyring-manager.js +23 -2437
- package/cjs/keyring-manager.js.map +1 -1
- package/cjs/software.js +58 -0
- package/cjs/software.js.map +1 -0
- package/cjs/storage-core.js +227 -0
- package/cjs/storage-core.js.map +1 -0
- package/cjs/storage.js +15 -210
- package/cjs/storage.js.map +1 -1
- package/cjs/transactions/ethereum.js +121 -29
- package/cjs/transactions/ethereum.js.map +1 -1
- package/cjs/transactions/evm-local-signer.js +11 -1
- package/cjs/transactions/evm-local-signer.js.map +1 -1
- package/cjs/transactions/hardware-psbt.js +167 -0
- package/cjs/transactions/hardware-psbt.js.map +1 -0
- package/cjs/transactions/syscoin-core.js +651 -0
- package/cjs/transactions/syscoin-core.js.map +1 -0
- package/cjs/transactions/syscoin.js +8 -768
- package/cjs/transactions/syscoin.js.map +1 -1
- package/cjs/types.js.map +1 -1
- package/package.json +38 -4
- package/types/keyring-core.d.ts +257 -0
- package/types/keyring-manager.d.ts +5 -223
- package/types/software.d.ts +23 -0
- package/types/storage-core.d.ts +22 -0
- package/types/storage.d.ts +1 -4
- package/types/transactions/ethereum.d.ts +16 -6
- package/types/transactions/evm-local-signer.d.ts +3 -1
- package/types/transactions/hardware-psbt.d.ts +7 -0
- package/types/transactions/syscoin-core.d.ts +92 -0
- package/types/transactions/syscoin.d.ts +8 -67
- package/types/types.d.ts +10 -0
- package/cjs/transactions/__tests__/integration.test.js +0 -237
- package/cjs/transactions/__tests__/integration.test.js.map +0 -1
- package/cjs/transactions/__tests__/syscoin.test.js +0 -361
- package/cjs/transactions/__tests__/syscoin.test.js.map +0 -1
- package/types/transactions/__tests__/integration.test.d.ts +0 -1
- package/types/transactions/__tests__/syscoin.test.d.ts +0 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** A host-owned namespace containing one wallet authority's logical records. */
|
|
2
|
+
export interface VaultStoragePort {
|
|
3
|
+
get(key: string): Promise<unknown>;
|
|
4
|
+
set(key: string, value: unknown): Promise<void>;
|
|
5
|
+
/** Atomically creates the entire batch only when every key is absent. */
|
|
6
|
+
createManyIfAbsent(items: Record<string, unknown>): Promise<boolean>;
|
|
7
|
+
}
|
|
8
|
+
export interface VaultPersistence {
|
|
9
|
+
setEncryptedVault(decryptedVault: any, pwd: string, freshVaultKeys?: {
|
|
10
|
+
salt: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
getDecryptedVault(pwd: string, legacyPassword?: string): Promise<any>;
|
|
13
|
+
}
|
|
14
|
+
export declare class VaultAuthenticationError extends Error {
|
|
15
|
+
readonly code = "INVALID_PASSWORD";
|
|
16
|
+
constructor();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create once per wallet authority and share across its network keyrings.
|
|
20
|
+
* The host owns storage durability and cross-context atomic creation.
|
|
21
|
+
*/
|
|
22
|
+
export declare const createVaultPersistence: (storage: VaultStoragePort) => VaultPersistence;
|
package/types/storage.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
export declare class VaultAuthenticationError extends Error {
|
|
2
|
-
readonly code = "INVALID_PASSWORD";
|
|
3
|
-
constructor();
|
|
4
|
-
}
|
|
5
1
|
export declare const setEncryptedVault: (decryptedVault: any, pwd: string, freshVaultKeys?: {
|
|
6
2
|
salt: string;
|
|
7
3
|
}) => Promise<void>;
|
|
8
4
|
export declare const getDecryptedVault: (pwd: string, legacyPassword?: string) => Promise<any>;
|
|
5
|
+
export { VaultAuthenticationError } from './storage-core';
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { TypedMessage, SignTypedDataVersion, TypedDataV1 } from '@metamask/eth-sig-util';
|
|
2
2
|
import { INetwork } from '@sidhujag/sysweb3-network';
|
|
3
3
|
import { BigNumber, TransactionResponse } from '../ethers-v6';
|
|
4
|
-
import { LedgerKeyring } from '../ledger';
|
|
5
4
|
import { CustomJsonRpcProvider } from '../providers';
|
|
6
|
-
import { TrezorKeyring } from '../trezor';
|
|
7
5
|
import { IResponseFromSendErcSignedTransaction, ISendSignedErcTransactionProps, IEthereumTransactions, IEvmCancellationOptions, IEvmReplacementOptions, IEvmSendOptions, SimpleTransactionRequest, KeyringAccountType, accountType, IGasParams } from '../types';
|
|
8
|
-
|
|
6
|
+
import type { LedgerKeyring } from '../ledger';
|
|
7
|
+
import type { TrezorKeyring } from '../trezor';
|
|
8
|
+
/** Minimal trusted device capabilities used by EVM transaction routing. */
|
|
9
|
+
export interface EthereumLedgerSigner {
|
|
10
|
+
evm: Pick<LedgerKeyring['evm'], 'signTypedData' | 'signPersonalMessage' | 'signEVMTransaction'>;
|
|
11
|
+
verifyUtxoAddress: LedgerKeyring['verifyUtxoAddress'];
|
|
12
|
+
}
|
|
13
|
+
export type EthereumTrezorSigner = Pick<TrezorKeyring, 'signTypedData' | 'signMessage' | 'signEthTransaction' | 'verifyUtxoAddress'>;
|
|
14
|
+
export declare class EthereumTransactions<TLedger extends EthereumLedgerSigner | undefined = LedgerKeyring, TTrezor extends EthereumTrezorSigner | undefined = TrezorKeyring> implements IEthereumTransactions {
|
|
9
15
|
private _web3Provider;
|
|
10
16
|
private _web3ProviderKey?;
|
|
11
|
-
trezorSigner:
|
|
12
|
-
ledgerSigner:
|
|
17
|
+
trezorSigner: TTrezor;
|
|
18
|
+
ledgerSigner: TLedger;
|
|
13
19
|
private getNetwork;
|
|
14
20
|
private captureSigningContext?;
|
|
15
21
|
private abortController;
|
|
@@ -29,7 +35,10 @@ export declare class EthereumTransactions implements IEthereumTransactions {
|
|
|
29
35
|
activeAccountId: number;
|
|
30
36
|
activeAccountType: KeyringAccountType;
|
|
31
37
|
activeNetwork: INetwork;
|
|
32
|
-
}, ledgerSigner:
|
|
38
|
+
}, ledgerSigner: TLedger, trezorSigner: TTrezor, captureSigningContext?: () => () => void);
|
|
39
|
+
private requireLedgerSigner;
|
|
40
|
+
private requireTrezorSigner;
|
|
41
|
+
private assertHardwareSignerAvailable;
|
|
33
42
|
private captureEvmSigningContext;
|
|
34
43
|
get web3Provider(): CustomJsonRpcProvider;
|
|
35
44
|
private ensureProvidersInitialized;
|
|
@@ -66,6 +75,7 @@ export declare class EthereumTransactions implements IEthereumTransactions {
|
|
|
66
75
|
cancelSentTransaction: (txHash: string, isLegacy: boolean | undefined, fallbackNonce: number | undefined, options: IEvmCancellationOptions) => Promise<{
|
|
67
76
|
error?: boolean;
|
|
68
77
|
isCanceled: boolean;
|
|
78
|
+
maximumFee?: string;
|
|
69
79
|
transaction?: TransactionResponse;
|
|
70
80
|
}>;
|
|
71
81
|
sendFormattedTransaction: (params: SimpleTransactionRequest, isLegacy?: boolean, options?: IEvmSendOptions) => Promise<any>;
|
|
@@ -20,5 +20,7 @@ export declare const hashPersonalMessage: (message: Uint8Array) => string;
|
|
|
20
20
|
export declare const signPersonalMessage: (message: string | Uint8Array, privateKey: string | Uint8Array) => string;
|
|
21
21
|
export declare const parsePersonalMessage: (hexMessage: string) => string;
|
|
22
22
|
export declare const signTransaction: (transaction: TransactionRequest, privateKey: string | Uint8Array) => string;
|
|
23
|
-
export declare const sendLocalEvmTransaction: (provider: CustomJsonRpcProvider, privateKey: string, transaction: Deferrable<Record<string, any>>, beforeBroadcast?: () => void, beforeSign?: () => void
|
|
23
|
+
export declare const sendLocalEvmTransaction: (provider: CustomJsonRpcProvider, privateKey: string, transaction: Deferrable<Record<string, any>>, beforeBroadcast?: () => void, beforeSign?: () => void,
|
|
24
|
+
/** Synchronous final-envelope check; throw to reject. Promise results are rejected. */
|
|
25
|
+
validateBeforeSign?: (transaction: TransactionRequest) => void) => Promise<any>;
|
|
24
26
|
export declare const sameAddress: (left: string, right: string) => boolean;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type ISyscoinHardwareSigner } from './syscoin-core';
|
|
2
|
+
import type { LedgerKeyring } from '../ledger';
|
|
3
|
+
import type { TrezorKeyring } from '../trezor';
|
|
4
|
+
/** Legacy device adapter. The software transaction engine never imports it. */
|
|
5
|
+
export declare function createLedgerPsbtSigner(ledger: LedgerKeyring): ISyscoinHardwareSigner;
|
|
6
|
+
/** Keep Trezor conversion and signing outside the software-only import graph. */
|
|
7
|
+
export declare function createTrezorPsbtSigner(trezor: TrezorKeyring): ISyscoinHardwareSigner;
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { ITxid, txUtils } from '@sidhujag/sysweb3-utils';
|
|
2
|
+
import { Psbt } from 'bitcoinjs-lib';
|
|
3
|
+
import { ISyscoinTransactions, KeyringAccountType, accountType } from '../types';
|
|
4
|
+
import { ExcludedOutpoint } from '../utils/excluded-utxos';
|
|
5
|
+
import { type PsbtAccountScope } from '../utils/psbt-account-scope';
|
|
6
|
+
import type { SyscoinHDSigner } from '../signers';
|
|
7
|
+
import type { INetwork } from '@sidhujag/sysweb3-network';
|
|
8
|
+
/** A hardware operation receives only its selected public account/context. */
|
|
9
|
+
export interface ISyscoinHardwareSigningRequest {
|
|
10
|
+
readonly account: Readonly<{
|
|
11
|
+
id: number;
|
|
12
|
+
xpub: string;
|
|
13
|
+
}>;
|
|
14
|
+
assertCurrent: () => void;
|
|
15
|
+
getRawTransaction?: ReturnType<typeof txUtils>['getRawTransaction'];
|
|
16
|
+
readonly network: Readonly<INetwork>;
|
|
17
|
+
psbt: Psbt;
|
|
18
|
+
scope: PsbtAccountScope;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Trusted wallet-authority adapter, not an untrusted plugin entry point.
|
|
22
|
+
* Implementations must preserve the reviewed unsigned transaction and enforce
|
|
23
|
+
* device signature/account-scope validation before returning the signed PSBT.
|
|
24
|
+
*/
|
|
25
|
+
export type ISyscoinHardwareSigner = (request: ISyscoinHardwareSigningRequest) => Promise<Psbt>;
|
|
26
|
+
export interface ISyscoinHardwareSigners {
|
|
27
|
+
ledger?: ISyscoinHardwareSigner;
|
|
28
|
+
trezor?: ISyscoinHardwareSigner;
|
|
29
|
+
}
|
|
30
|
+
export declare const createHardwareSignerUnavailableError: (hardware: string) => Error & {
|
|
31
|
+
code: string;
|
|
32
|
+
};
|
|
33
|
+
export declare class SyscoinTransactionsCore implements ISyscoinTransactions {
|
|
34
|
+
private getSigner;
|
|
35
|
+
private getReadOnlySigner;
|
|
36
|
+
private hardwareSigners;
|
|
37
|
+
private getState;
|
|
38
|
+
private getAddress;
|
|
39
|
+
private captureSigningContext?;
|
|
40
|
+
constructor(getSyscoinSigner: () => {
|
|
41
|
+
hd: SyscoinHDSigner;
|
|
42
|
+
main: any;
|
|
43
|
+
}, getReadOnlySigner: () => {
|
|
44
|
+
main: any;
|
|
45
|
+
}, getState: () => {
|
|
46
|
+
accounts: {
|
|
47
|
+
HDAccount: accountType;
|
|
48
|
+
Imported: accountType;
|
|
49
|
+
Ledger: accountType;
|
|
50
|
+
Trezor: accountType;
|
|
51
|
+
};
|
|
52
|
+
activeAccountId: number;
|
|
53
|
+
activeAccountType: KeyringAccountType;
|
|
54
|
+
activeNetwork: INetwork;
|
|
55
|
+
}, getAddress: (xpub: string, isChangeAddress: boolean) => Promise<string>, hardwareSigners?: ISyscoinHardwareSigners, captureSigningContext?: () => () => void);
|
|
56
|
+
private getTransactionPSBT;
|
|
57
|
+
decodeRawTransaction: (psbtOrHex: any, isRawHex?: boolean) => any;
|
|
58
|
+
private feeCache;
|
|
59
|
+
getRecommendedFee: (explorerUrl: string) => Promise<number>;
|
|
60
|
+
txUtilsFunctions: () => {
|
|
61
|
+
getRawTransaction: (explorerUrl: string, txid: string) => Promise<any>;
|
|
62
|
+
};
|
|
63
|
+
private signPSBTWithSigner;
|
|
64
|
+
private createNativeSweepPSBT;
|
|
65
|
+
private createUnsignedPSBT;
|
|
66
|
+
private signPSBTWithMethod;
|
|
67
|
+
getEstimateSysTransactionFee: ({ txOptions, isMax, nativeSweep, amount, receivingAddress, feeRate, token, excludedOutpoints, }: {
|
|
68
|
+
amount: number | string;
|
|
69
|
+
feeRate?: number;
|
|
70
|
+
receivingAddress: string;
|
|
71
|
+
token?: {
|
|
72
|
+
guid: string;
|
|
73
|
+
symbol?: string;
|
|
74
|
+
} | null;
|
|
75
|
+
txOptions?: any;
|
|
76
|
+
isMax?: boolean | false;
|
|
77
|
+
nativeSweep?: boolean;
|
|
78
|
+
excludedOutpoints?: readonly ExcludedOutpoint[];
|
|
79
|
+
}) => Promise<{
|
|
80
|
+
grossAmount?: string | undefined;
|
|
81
|
+
recipientAmount?: string | undefined;
|
|
82
|
+
fee: number;
|
|
83
|
+
psbt: any;
|
|
84
|
+
}>;
|
|
85
|
+
private sendSignedTransaction;
|
|
86
|
+
signPSBT: ({ psbt, isTrezor, isLedger, }: {
|
|
87
|
+
psbt: any;
|
|
88
|
+
isTrezor?: boolean;
|
|
89
|
+
isLedger?: boolean;
|
|
90
|
+
}) => Promise<any>;
|
|
91
|
+
sendTransaction: (psbt: any) => Promise<ITxid>;
|
|
92
|
+
}
|
|
@@ -1,68 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export declare class SyscoinTransactions implements ISyscoinTransactions {
|
|
9
|
-
private getSigner;
|
|
10
|
-
private getReadOnlySigner;
|
|
11
|
-
private trezor;
|
|
12
|
-
private ledger;
|
|
13
|
-
private getState;
|
|
14
|
-
private getAddress;
|
|
15
|
-
private captureSigningContext?;
|
|
16
|
-
constructor(getSyscoinSigner: () => {
|
|
17
|
-
hd: SyscoinHDSigner;
|
|
18
|
-
main: any;
|
|
19
|
-
}, getReadOnlySigner: () => {
|
|
20
|
-
main: any;
|
|
21
|
-
}, getState: () => {
|
|
22
|
-
accounts: {
|
|
23
|
-
HDAccount: accountType;
|
|
24
|
-
Imported: accountType;
|
|
25
|
-
Ledger: accountType;
|
|
26
|
-
Trezor: accountType;
|
|
27
|
-
};
|
|
28
|
-
activeAccountId: number;
|
|
29
|
-
activeAccountType: KeyringAccountType;
|
|
30
|
-
activeNetwork: INetwork;
|
|
31
|
-
}, getAddress: (xpub: string, isChangeAddress: boolean) => Promise<string>, ledgerSigner: LedgerKeyring, trezorSigner: TrezorKeyring, captureSigningContext?: () => () => void);
|
|
32
|
-
private getTransactionPSBT;
|
|
33
|
-
decodeRawTransaction: (psbtOrHex: any, isRawHex?: boolean) => any;
|
|
34
|
-
private feeCache;
|
|
35
|
-
getRecommendedFee: (explorerUrl: string) => Promise<number>;
|
|
36
|
-
txUtilsFunctions: () => {
|
|
37
|
-
getRawTransaction: (explorerUrl: string, txid: string) => Promise<any>;
|
|
38
|
-
};
|
|
39
|
-
private signPSBTWithSigner;
|
|
40
|
-
private createNativeSweepPSBT;
|
|
41
|
-
private createUnsignedPSBT;
|
|
42
|
-
private signPSBTWithMethod;
|
|
43
|
-
getEstimateSysTransactionFee: ({ txOptions, isMax, nativeSweep, amount, receivingAddress, feeRate, token, excludedOutpoints, }: {
|
|
44
|
-
amount: number | string;
|
|
45
|
-
feeRate?: number;
|
|
46
|
-
receivingAddress: string;
|
|
47
|
-
token?: {
|
|
48
|
-
guid: string;
|
|
49
|
-
symbol?: string;
|
|
50
|
-
} | null;
|
|
51
|
-
txOptions?: any;
|
|
52
|
-
isMax?: boolean | false;
|
|
53
|
-
nativeSweep?: boolean;
|
|
54
|
-
excludedOutpoints?: readonly ExcludedOutpoint[];
|
|
55
|
-
}) => Promise<{
|
|
56
|
-
grossAmount?: string | undefined;
|
|
57
|
-
recipientAmount?: string | undefined;
|
|
58
|
-
fee: number;
|
|
59
|
-
psbt: any;
|
|
60
|
-
}>;
|
|
61
|
-
private sendSignedTransaction;
|
|
62
|
-
signPSBT: ({ psbt, isTrezor, isLedger, }: {
|
|
63
|
-
psbt: any;
|
|
64
|
-
isTrezor?: boolean;
|
|
65
|
-
isLedger?: boolean;
|
|
66
|
-
}) => Promise<any>;
|
|
67
|
-
sendTransaction: (psbt: any) => Promise<ITxid>;
|
|
1
|
+
import { SyscoinTransactionsCore } from './syscoin-core';
|
|
2
|
+
import type { LedgerKeyring } from '../ledger';
|
|
3
|
+
import type { TrezorKeyring } from '../trezor';
|
|
4
|
+
type CoreArguments = ConstructorParameters<typeof SyscoinTransactionsCore>;
|
|
5
|
+
/** Legacy constructor: preserve device arguments while composing shared logic. */
|
|
6
|
+
export declare class SyscoinTransactions extends SyscoinTransactionsCore {
|
|
7
|
+
constructor(getSyscoinSigner: CoreArguments[0], getReadOnlySigner: CoreArguments[1], getState: CoreArguments[2], getAddress: CoreArguments[3], ledgerSigner: LedgerKeyring, trezorSigner: TrezorKeyring, captureSigningContext?: CoreArguments[5]);
|
|
68
8
|
}
|
|
9
|
+
export {};
|
package/types/types.d.ts
CHANGED
|
@@ -56,6 +56,15 @@ export interface IEvmReplacementOptions {
|
|
|
56
56
|
beforeBroadcast?: () => void;
|
|
57
57
|
}
|
|
58
58
|
export interface IEvmCancellationOptions {
|
|
59
|
+
/** Select the locally controlled outer gas payer for a smart-account transaction. */
|
|
60
|
+
targetAccount?: {
|
|
61
|
+
id: number;
|
|
62
|
+
type: KeyringAccountType;
|
|
63
|
+
};
|
|
64
|
+
/** Read-only preview; never requests credentials, a device signature or broadcast. */
|
|
65
|
+
previewOnly?: boolean;
|
|
66
|
+
/** Required for sending: maximum execution gas fee in decimal wei approved by the user. */
|
|
67
|
+
approvedMaximumFee?: string;
|
|
59
68
|
/** Synchronous host guard for selection or session state outside the keyring. */
|
|
60
69
|
assertCurrentContext: () => void;
|
|
61
70
|
/**
|
|
@@ -72,6 +81,7 @@ export interface IEthereumTransactions {
|
|
|
72
81
|
cancelSentTransaction: (txHash: string, isLegacy: boolean | undefined, fallbackNonce: number | undefined, options: IEvmCancellationOptions) => Promise<{
|
|
73
82
|
error?: boolean;
|
|
74
83
|
isCanceled: boolean;
|
|
84
|
+
maximumFee?: string;
|
|
75
85
|
transaction?: TransactionResponse;
|
|
76
86
|
}>;
|
|
77
87
|
decryptMessage: (msgParams: string[]) => string;
|
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const types_1 = require("../../types");
|
|
4
|
-
const syscoin_1 = require("../syscoin");
|
|
5
|
-
// Integration tests for the complete transaction flow
|
|
6
|
-
describe('PSBT Transaction Flow Integration', () => {
|
|
7
|
-
let syscoinTransactions;
|
|
8
|
-
let mockSigner;
|
|
9
|
-
let mockState;
|
|
10
|
-
let mockLedger;
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
// Setup comprehensive mocks
|
|
13
|
-
mockSigner = {
|
|
14
|
-
hd: {
|
|
15
|
-
Signer: { network: 'mainnet' },
|
|
16
|
-
sign: jest.fn().mockResolvedValue('signed-psbt'),
|
|
17
|
-
},
|
|
18
|
-
main: {
|
|
19
|
-
blockbookURL: 'https://blockbook.test',
|
|
20
|
-
createPSBTFromRes: jest.fn().mockResolvedValue('unsigned-psbt'),
|
|
21
|
-
assetAllocationSend: jest.fn().mockResolvedValue({
|
|
22
|
-
psbt: 'unsigned-token-psbt',
|
|
23
|
-
}),
|
|
24
|
-
send: jest.fn().mockResolvedValue({
|
|
25
|
-
extractTransaction: () => ({ getId: () => 'final-txid' }),
|
|
26
|
-
}),
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
mockState = {
|
|
30
|
-
activeAccountId: 0,
|
|
31
|
-
activeAccountType: types_1.KeyringAccountType.HDAccount,
|
|
32
|
-
accounts: {
|
|
33
|
-
[types_1.KeyringAccountType.HDAccount]: {
|
|
34
|
-
0: { xpub: 'xpub123', id: 0 },
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
activeNetwork: { currency: 'sys', chainId: 57 },
|
|
38
|
-
};
|
|
39
|
-
mockLedger = {
|
|
40
|
-
ledgerTransport: true,
|
|
41
|
-
ledgerUtxoClient: {
|
|
42
|
-
getMasterFingerprint: jest.fn().mockResolvedValue('fingerprint'),
|
|
43
|
-
signPsbt: jest.fn().mockResolvedValue([[0, { signature: 'sig' }]]),
|
|
44
|
-
},
|
|
45
|
-
};
|
|
46
|
-
const mockGetAddress = jest.fn().mockResolvedValue('change-address');
|
|
47
|
-
const mockTrezor = {
|
|
48
|
-
init: jest.fn(),
|
|
49
|
-
convertToTrezorFormat: jest.fn(),
|
|
50
|
-
signUtxoTransaction: jest.fn(),
|
|
51
|
-
};
|
|
52
|
-
syscoinTransactions = new syscoin_1.SyscoinTransactions(() => mockSigner, () => mockSigner, // getReadOnlySigner - same mock for testing
|
|
53
|
-
() => mockState, mockGetAddress, mockLedger, mockTrezor);
|
|
54
|
-
});
|
|
55
|
-
describe('Complete Native Transaction Flow', () => {
|
|
56
|
-
it('should handle native transaction from creation to broadcast', async () => {
|
|
57
|
-
// Step 1: Create unsigned PSBT and get fee
|
|
58
|
-
const { fee, psbt: unsignedPsbt } = await syscoinTransactions.getEstimateSysTransactionFee({
|
|
59
|
-
amount: 1,
|
|
60
|
-
receivingAddress: 'sys1qtest',
|
|
61
|
-
feeRate: 0.00001,
|
|
62
|
-
});
|
|
63
|
-
expect(fee).toBeGreaterThan(0);
|
|
64
|
-
expect(unsignedPsbt).toBeDefined();
|
|
65
|
-
// Step 2: Sign the PSBT
|
|
66
|
-
const signedPsbt = await syscoinTransactions.signPSBT({
|
|
67
|
-
psbt: unsignedPsbt,
|
|
68
|
-
isTrezor: false,
|
|
69
|
-
isLedger: false,
|
|
70
|
-
});
|
|
71
|
-
// Step 3: Send the signed PSBT
|
|
72
|
-
const result = await syscoinTransactions.sendTransaction(signedPsbt);
|
|
73
|
-
expect(result.txid).toBe('final-txid');
|
|
74
|
-
expect(mockSigner.main.send).toHaveBeenCalledWith(signedPsbt);
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
describe('Complete Token Transaction Flow', () => {
|
|
78
|
-
it('should handle token transaction from creation to broadcast', async () => {
|
|
79
|
-
// Mock token lookup
|
|
80
|
-
jest.doMock('@sidhujag/sysweb3-utils', () => ({
|
|
81
|
-
getAsset: jest.fn().mockResolvedValue({
|
|
82
|
-
assetGuid: 'token123',
|
|
83
|
-
decimals: 8,
|
|
84
|
-
}),
|
|
85
|
-
}));
|
|
86
|
-
// Step 1: Create unsigned token PSBT and get fee
|
|
87
|
-
const { fee, psbt: unsignedPsbt } = await syscoinTransactions.getEstimateSysTransactionFee({
|
|
88
|
-
amount: 100,
|
|
89
|
-
receivingAddress: 'sys1qtest',
|
|
90
|
-
token: { guid: 'token123', symbol: 'TEST' },
|
|
91
|
-
});
|
|
92
|
-
expect(fee).toBeGreaterThan(0);
|
|
93
|
-
expect(unsignedPsbt).toBeDefined();
|
|
94
|
-
expect(mockSigner.main.assetAllocationSend).toHaveBeenCalledWith(expect.any(Object), expect.any(Map), 'change-address', expect.any(Object), 'xpub123');
|
|
95
|
-
// Step 2: Sign the token PSBT
|
|
96
|
-
const signedPsbt = await syscoinTransactions.signPSBT({
|
|
97
|
-
psbt: unsignedPsbt,
|
|
98
|
-
isTrezor: false,
|
|
99
|
-
isLedger: false,
|
|
100
|
-
});
|
|
101
|
-
// Step 3: Send the signed PSBT
|
|
102
|
-
const result = await syscoinTransactions.sendTransaction(signedPsbt);
|
|
103
|
-
expect(result.txid).toBe('final-txid');
|
|
104
|
-
});
|
|
105
|
-
});
|
|
106
|
-
describe('Hardware Wallet Integration', () => {
|
|
107
|
-
it('should handle Trezor transaction flow', async () => {
|
|
108
|
-
const mockTrezor = {
|
|
109
|
-
init: jest.fn(),
|
|
110
|
-
convertToTrezorFormat: jest.fn().mockReturnValue('trezor-format'),
|
|
111
|
-
signUtxoTransaction: jest.fn().mockResolvedValue('trezor-signed-psbt'),
|
|
112
|
-
};
|
|
113
|
-
syscoinTransactions.trezor = mockTrezor;
|
|
114
|
-
// Create unsigned PSBT
|
|
115
|
-
const { fee, psbt: unsignedPsbt } = await syscoinTransactions.getEstimateSysTransactionFee({
|
|
116
|
-
amount: 1,
|
|
117
|
-
receivingAddress: 'sys1qtest',
|
|
118
|
-
});
|
|
119
|
-
expect(fee).toBeGreaterThan(0);
|
|
120
|
-
expect(unsignedPsbt).toBeDefined();
|
|
121
|
-
// Sign with Trezor
|
|
122
|
-
const signedPsbt = await syscoinTransactions.signPSBT({
|
|
123
|
-
psbt: unsignedPsbt,
|
|
124
|
-
isTrezor: true,
|
|
125
|
-
});
|
|
126
|
-
expect(mockTrezor.init).toHaveBeenCalled();
|
|
127
|
-
expect(mockTrezor.signUtxoTransaction).toHaveBeenCalled();
|
|
128
|
-
expect(signedPsbt).toBe('trezor-signed-psbt');
|
|
129
|
-
// Send
|
|
130
|
-
const result = await syscoinTransactions.sendTransaction(signedPsbt);
|
|
131
|
-
expect(result.txid).toBe('final-txid');
|
|
132
|
-
});
|
|
133
|
-
it('should handle Ledger transaction flow', async () => {
|
|
134
|
-
mockState.activeAccountType = types_1.KeyringAccountType.Ledger;
|
|
135
|
-
mockState.accounts[types_1.KeyringAccountType.Ledger] = {
|
|
136
|
-
0: { xpub: 'ledger-xpub', id: 0, isLedgerWallet: true },
|
|
137
|
-
};
|
|
138
|
-
// Mock Psbt for Ledger
|
|
139
|
-
jest.doMock('syscoinjs-lib', () => ({
|
|
140
|
-
Psbt: {
|
|
141
|
-
fromBase64: jest.fn().mockReturnValue({
|
|
142
|
-
updateInput: jest.fn(),
|
|
143
|
-
finalizeAllInputs: jest.fn(),
|
|
144
|
-
toBase64: jest.fn().mockReturnValue('ledger-signed-psbt'),
|
|
145
|
-
}),
|
|
146
|
-
},
|
|
147
|
-
}));
|
|
148
|
-
// Create unsigned PSBT
|
|
149
|
-
const { fee, psbt: unsignedPsbt } = await syscoinTransactions.getEstimateSysTransactionFee({
|
|
150
|
-
amount: 1,
|
|
151
|
-
receivingAddress: 'sys1qtest',
|
|
152
|
-
});
|
|
153
|
-
expect(fee).toBeGreaterThan(0);
|
|
154
|
-
expect(unsignedPsbt).toBeDefined();
|
|
155
|
-
// Sign with Ledger
|
|
156
|
-
const signedPsbt = await syscoinTransactions.signPSBT({
|
|
157
|
-
psbt: unsignedPsbt,
|
|
158
|
-
isLedger: true,
|
|
159
|
-
});
|
|
160
|
-
expect(mockLedger.ledgerUtxoClient.signPsbt).toHaveBeenCalled();
|
|
161
|
-
expect(signedPsbt).toBeDefined();
|
|
162
|
-
// Send
|
|
163
|
-
const result = await syscoinTransactions.sendTransaction(signedPsbt);
|
|
164
|
-
expect(result.txid).toBe('final-txid');
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
describe('Error Scenarios', () => {
|
|
168
|
-
it('should handle signing errors separately from sending errors', async () => {
|
|
169
|
-
// Test signing error
|
|
170
|
-
mockSigner.hd.sign = jest
|
|
171
|
-
.fn()
|
|
172
|
-
.mockRejectedValue(new Error('Device disconnected'));
|
|
173
|
-
await expect(syscoinTransactions.getEstimateSysTransactionFee({
|
|
174
|
-
amount: 1,
|
|
175
|
-
receivingAddress: 'sys1qtest',
|
|
176
|
-
})).rejects.toThrow('Failed to sign transaction: Device disconnected');
|
|
177
|
-
// Test sending error
|
|
178
|
-
mockSigner.main.send = jest
|
|
179
|
-
.fn()
|
|
180
|
-
.mockRejectedValue(new Error('Network error'));
|
|
181
|
-
await expect(syscoinTransactions.sendTransaction('valid-psbt')).rejects.toThrow('Failed to send transaction');
|
|
182
|
-
});
|
|
183
|
-
it('should require PSBT for sendTransaction', async () => {
|
|
184
|
-
await expect(syscoinTransactions.sendTransaction('')).rejects.toThrow('Pre-signed PSBT is required');
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
describe('Fee Calculation', () => {
|
|
188
|
-
it('should calculate correct fees for multi-input transactions', async () => {
|
|
189
|
-
// Mock multiple UTXOs
|
|
190
|
-
const mockUtxos = [
|
|
191
|
-
{ txid: 'tx1', vout: 0, value: '50000000' },
|
|
192
|
-
{ txid: 'tx2', vout: 1, value: '30000000' },
|
|
193
|
-
{ txid: 'tx3', vout: 0, value: '20000000' },
|
|
194
|
-
];
|
|
195
|
-
jest.doMock('syscoinjs-lib', () => ({
|
|
196
|
-
utils: {
|
|
197
|
-
fetchBackendUTXOS: jest.fn().mockResolvedValue(mockUtxos),
|
|
198
|
-
sanitizeBlockbookUTXOs: jest.fn().mockReturnValue(mockUtxos),
|
|
199
|
-
},
|
|
200
|
-
}));
|
|
201
|
-
jest.doMock('coinselectsyscoin', () => ({
|
|
202
|
-
utils: {
|
|
203
|
-
transactionBytes: jest.fn().mockReturnValue(500), // Larger tx with multiple inputs
|
|
204
|
-
},
|
|
205
|
-
}));
|
|
206
|
-
const { fee } = await syscoinTransactions.getEstimateSysTransactionFee({
|
|
207
|
-
amount: 0.8, // Amount that requires multiple UTXOs
|
|
208
|
-
receivingAddress: 'sys1qtest',
|
|
209
|
-
feeRate: 0.00001,
|
|
210
|
-
});
|
|
211
|
-
// Fee should be proportional to transaction size
|
|
212
|
-
expect(fee).toBeGreaterThan(0.00001); // More than minimum
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
describe('RBF Support', () => {
|
|
216
|
-
it('should create RBF-enabled transactions by default', async () => {
|
|
217
|
-
await syscoinTransactions.getEstimateSysTransactionFee({
|
|
218
|
-
amount: 1,
|
|
219
|
-
receivingAddress: 'sys1qtest',
|
|
220
|
-
});
|
|
221
|
-
// Check that RBF was enabled in the transaction options
|
|
222
|
-
expect(mockSigner.main.createPSBTFromRes).toHaveBeenCalled();
|
|
223
|
-
const callArgs = mockSigner.main.createPSBTFromRes.mock.calls[0];
|
|
224
|
-
expect(callArgs[0]).toMatchObject({ rbf: true });
|
|
225
|
-
});
|
|
226
|
-
it('should disable RBF when requested', async () => {
|
|
227
|
-
await syscoinTransactions.getEstimateSysTransactionFee({
|
|
228
|
-
amount: 1,
|
|
229
|
-
receivingAddress: 'sys1qtest',
|
|
230
|
-
txOptions: { rbf: false },
|
|
231
|
-
});
|
|
232
|
-
const callArgs = mockSigner.main.createPSBTFromRes.mock.calls[0];
|
|
233
|
-
expect(callArgs[0]).toMatchObject({ rbf: false });
|
|
234
|
-
});
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
//# sourceMappingURL=integration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../../../src/transactions/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
|