Skip to content

Commit

Permalink
feat: support neurai
Browse files Browse the repository at this point in the history
  • Loading branch information
ByteZhang1024 committed Mar 15, 2024
1 parent 96fb13f commit 1136d8e
Show file tree
Hide file tree
Showing 20 changed files with 393 additions and 40 deletions.
4 changes: 4 additions & 0 deletions packages/engine/src/managers/derivation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
COINTYPE_LTC,
COINTYPE_NEAR,
COINTYPE_NERVOS,
COINTYPE_NEURAI,
COINTYPE_NEXA,
COINTYPE_NOSTR,
COINTYPE_SOL,
Expand All @@ -41,6 +42,7 @@ import {
IMPL_LTC,
IMPL_NEAR,
IMPL_NERVOS,
IMPL_NEURAI,
IMPL_NOSTR,
IMPL_SOL,
IMPL_STC,
Expand Down Expand Up @@ -87,6 +89,7 @@ const purposeMap: Record<string, Array<number>> = {
[IMPL_KASPA]: [44],
[IMPL_NOSTR]: [44],
[IMPL_NERVOS]: [44],
[IMPL_NEURAI]: [44],
};

// derive path template by coin types.
Expand Down Expand Up @@ -121,6 +124,7 @@ const derivationPathTemplates: Record<string, string> = {
[COINTYPE_LIGHTNING_TESTNET]: `m/44'/${COINTYPE_LIGHTNING_TESTNET}'/${INCREMENT_LEVEL_TAG}`,
[COINTYPE_NOSTR]: `m/44'/${COINTYPE_NOSTR}'/${INCREMENT_LEVEL_TAG}'`,
[COINTYPE_NERVOS]: `m/44'/${COINTYPE_NERVOS}'/0'/0/${INCREMENT_LEVEL_TAG}`,
[COINTYPE_NEURAI]: `m/44'/${COINTYPE_NEURAI}'/${INCREMENT_LEVEL_TAG}'`,
};

function getDerivationPaths(
Expand Down
14 changes: 13 additions & 1 deletion packages/engine/src/managers/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
COINTYPE_LTC,
COINTYPE_NEAR,
COINTYPE_NERVOS,
COINTYPE_NEURAI,
COINTYPE_NEXA,
COINTYPE_NOSTR,
COINTYPE_SOL,
Expand All @@ -45,6 +46,7 @@ import {
IMPL_LTC,
IMPL_NEAR,
IMPL_NERVOS,
IMPL_NEURAI,
IMPL_NEXA,
IMPL_NOSTR,
IMPL_SOL,
Expand Down Expand Up @@ -96,6 +98,7 @@ const implToCoinTypes: Partial<Record<string, string | string[]>> = {
[IMPL_LIGHTNING_TESTNET]: COINTYPE_LIGHTNING_TESTNET,
[IMPL_NOSTR]: COINTYPE_NOSTR,
[IMPL_NERVOS]: COINTYPE_NERVOS,
[IMPL_NEURAI]: COINTYPE_NEURAI,
};

const coinTypeToImpl: Record<string, string> = Object.fromEntries(
Expand Down Expand Up @@ -136,6 +139,7 @@ const implToAccountType: Record<string, AccountType> = {
[IMPL_LIGHTNING_TESTNET]: AccountType.VARIANT,
[IMPL_NOSTR]: AccountType.VARIANT,
[IMPL_NERVOS]: AccountType.SIMPLE,
[IMPL_NEURAI]: AccountType.UTXO,
};

function isCoinTypeCompatibleWithImpl(coinType: string, impl: string): boolean {
Expand Down Expand Up @@ -171,6 +175,7 @@ const defaultCurveMap: Record<string, Curve> = {
[IMPL_LIGHTNING_TESTNET]: Curve.SECP256K1,
[IMPL_NOSTR]: Curve.SECP256K1,
[IMPL_NERVOS]: Curve.SECP256K1,
[IMPL_NEURAI]: Curve.SECP256K1,
};

function getCurveByImpl(impl: string): string {
Expand Down Expand Up @@ -284,7 +289,14 @@ function migrateNextAccountIds(nextAccountIds: Record<string, number>) {
}

function isBtcLikeImpl(impl: string): boolean {
return [IMPL_BTC, IMPL_TBTC, IMPL_LTC, IMPL_BCH, IMPL_DOGE].includes(impl);
return [
IMPL_BTC,
IMPL_TBTC,
IMPL_LTC,
IMPL_BCH,
IMPL_DOGE,
IMPL_NEURAI,
].includes(impl);
}

export {
Expand Down
3 changes: 2 additions & 1 deletion packages/engine/src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
IMPL_BTC,
IMPL_DOGE,
IMPL_LTC,
IMPL_NEURAI,
IMPL_TBTC,
SEPERATOR,
} from '@onekeyhq/shared/src/engine/engineConsts';
Expand Down Expand Up @@ -76,7 +77,7 @@ function fromDBNetworkToChainInfo(dbNetwork: DBNetwork): ChainInfo {

let code = dbNetwork.id;
if (
[IMPL_BTC, IMPL_DOGE, IMPL_LTC, IMPL_BCH, IMPL_TBTC].includes(
[IMPL_BTC, IMPL_DOGE, IMPL_LTC, IMPL_BCH, IMPL_TBTC, IMPL_NEURAI].includes(
dbNetwork.impl,
)
) {
Expand Down
4 changes: 4 additions & 0 deletions packages/engine/src/vaults/factory.createVaultSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
IMPL_LTC,
IMPL_NEAR,
IMPL_NERVOS,
IMPL_NEURAI,
IMPL_NEXA,
IMPL_NOSTR,
IMPL_SOL,
Expand Down Expand Up @@ -129,6 +130,9 @@ export function createVaultSettings(options: {
if (impl === IMPL_NERVOS) {
return require('./impl/nervos/settings').default as IVaultSettings;
}
if (impl === IMPL_NEURAI) {
return require('./impl/neurai/settings').default as IVaultSettings;
}
throw new OneKeyInternalError(
`VaultSettings not found for: networkId=${options.networkId ?? ''}, impl=${
impl ?? ''
Expand Down
9 changes: 9 additions & 0 deletions packages/engine/src/vaults/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
IMPL_LTC,
IMPL_NEAR,
IMPL_NERVOS,
IMPL_NEURAI,
IMPL_NEXA,
IMPL_NOSTR,
IMPL_SOL,
Expand Down Expand Up @@ -55,6 +56,7 @@ import VaultHelperLightning from './impl/lightning-network/VaultHelper';
import VaultHelperLtc from './impl/ltc/VaultHelper';
import VaultHelperNear from './impl/near/VaultHelper';
import VaultHelperNervos from './impl/nervos/VaultHelper';
import VaultHelperNeurai from './impl/neurai/VaultHelper';
import VaultHelperNexa from './impl/nexa/VaultHelper';
import VaultHelperNostr from './impl/nostr/VaultHelper';
import VauleHelperSol from './impl/sol/VaultHelper';
Expand Down Expand Up @@ -152,6 +154,9 @@ export async function createVaultHelperInstance(
if (impl === IMPL_NERVOS) {
return new VaultHelperNervos(options);
}
if (impl === IMPL_NEURAI) {
return new VaultHelperNeurai(options);
}
throw new OneKeyInternalError(
`VaultHelper Class not found for: networkId=${options.networkId}, accountId=${options.accountId}`,
);
Expand Down Expand Up @@ -301,6 +306,10 @@ export async function createVaultInstance(options: IVaultOptions) {
const VaultNervos = (await import('./impl/nervos/Vault')).default;
vault = new VaultNervos(options);
}
if (network.impl === IMPL_NEURAI) {
const VaultNeurai = (await import('./impl/neurai/Vault')).default;
vault = new VaultNeurai(options);
}
if (!vault) {
throw new OneKeyInternalError(
`Vault Class not found for: networkId=${options.networkId}, accountId=${options.accountId}`,
Expand Down
65 changes: 57 additions & 8 deletions packages/engine/src/vaults/impl/nervos/Vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ import { KeyringWatching } from './KeyringWatching';
import settings from './settings';
import { isValidateAddress, scriptToAddress } from './utils/address';
import {
DEFAULT_CONFIRM_BLOCK,
fetchConfirmCellsByAddress,
getBalancesByAddress,
getConfirmBalancesByAddress,
getFrozenBalancesByAddress,
} from './utils/balance';
import { getConfig } from './utils/config';
import {
Expand Down Expand Up @@ -162,6 +165,27 @@ export default class Vault extends VaultBase {
return { responseTime: Math.floor(performance.now() - start), latestBlock };
}

override async getFrozenBalance({
password,
}: {
password?: string;
useRecycleBalance?: boolean;
ignoreInscriptions?: boolean;
useCustomAddressesBalance?: boolean;
} = {}): Promise<number | Record<string, number>> {
const indexer = await this.getIndexer();
const client = await this.getClient();
const dbAccount = await this.getDbAccount();
const balance = await getFrozenBalancesByAddress({
indexer,
address: dbAccount.address,
client,
});

const network = await this.engine.getNetwork(this.networkId);
return balance.shiftedBy(-network.decimals).toNumber();
}

override async getBalances(
requests: { address: string; tokenAddress?: string | undefined }[],
): Promise<(BigNumber | undefined)[]> {
Expand All @@ -174,7 +198,10 @@ export default class Vault extends VaultBase {
Object.entries(requestAddress).map(async ([address, tokens]) => {
try {
try {
balances.set(address, await getBalancesByAddress(indexer, address));
balances.set(
address,
await getBalancesByAddress({ indexer, address }),
);
} catch (e) {
// ignore
}
Expand Down Expand Up @@ -207,11 +234,11 @@ export default class Vault extends VaultBase {
const { address: from } = await this.getDbAccount();

const network = await this.getNetwork();
const confirmCellsByAddress = await fetchConfirmCellsByAddress(
const confirmCellsByAddress = await fetchConfirmCellsByAddress({
indexer,
from,
address: from,
client,
);
});
const transaction = prepareAndBuildTx({
confirmCells: confirmCellsByAddress,
from,
Expand Down Expand Up @@ -468,13 +495,27 @@ export default class Vault extends VaultBase {
txids: string[],
): Promise<(TransactionStatus | undefined)[]> {
const client = await this.getClient();
const currentBlockNumber = new BigNumber(
await client.getTipBlockNumber(),
16,
);

const txStatuses = new Map<string, TransactionStatus>();
for (const txid of txids) {
const tx = await client.getTransaction(txid);

let status = TransactionStatus.PENDING;
if (tx.txStatus.status === 'committed') {
status = TransactionStatus.CONFIRM_AND_SUCCESS;
if (tx.txStatus.blockHash) {
const blockHeader = await client.getHeader(
tx.txStatus.blockHash,
'0x1',
);
const isConfirmed = currentBlockNumber
.minus(new BigNumber(blockHeader.number, 16))
.isGreaterThanOrEqualTo(DEFAULT_CONFIRM_BLOCK);
if (tx.txStatus.status === 'committed' && isConfirmed) {
status = TransactionStatus.CONFIRM_AND_SUCCESS;
}
}
txStatuses.set(txid, status);
}
Expand Down Expand Up @@ -506,6 +547,10 @@ export default class Vault extends VaultBase {
});

const config = getConfig(await this.getNetworkChainId());
const currentBlockNumber = new BigNumber(
await client.getTipBlockNumber(),
16,
);

const txs = history.map(async (tx) => {
try {
Expand All @@ -521,7 +566,7 @@ export default class Vault extends VaultBase {
txStatus: { status },
transaction: { hash: txHash },
} = tx.txWithStatus;
const { timestamp } = tx.txBlockHeader;
const { timestamp, number: blockNumber } = tx.txBlockHeader;
const { inputs, outputs } = tx.txSkeleton;

const txid = txHash;
Expand Down Expand Up @@ -630,14 +675,18 @@ export default class Vault extends VaultBase {
.shiftedBy(-network.decimals)
.toFixed();

const isConfirmed = currentBlockNumber
.minus(new BigNumber(blockNumber, 16))
.isGreaterThanOrEqualTo(DEFAULT_CONFIRM_BLOCK);

const decodedTx: IDecodedTx = {
txid: txid ?? '',
owner: dbAccount.address,
signer: dbAccount.address,
nonce: 0,
actions,
status:
status === 'committed'
status === 'committed' && isConfirmed
? IDecodedTxStatus.Confirmed
: IDecodedTxStatus.Pending,
networkId: this.networkId,
Expand Down
Loading

0 comments on commit 1136d8e

Please sign in to comment.