-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'origin/dev' into feat/add-address-balan…
…ce-chronicle-nova
- Loading branch information
Showing
21 changed files
with
1,344 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export interface ISearchRequest { | ||
/** | ||
* The network to search on. | ||
*/ | ||
network: string; | ||
|
||
/** | ||
* The query to look for. | ||
*/ | ||
query: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* eslint-disable import/no-unresolved */ | ||
/* eslint-disable @typescript-eslint/no-unsafe-argument */ | ||
import { Block, OutputResponse } from "@iota/sdk-nova"; | ||
import { IAddressDetails } from "./IAddressDetails"; | ||
import { IResponse } from "../IResponse"; | ||
|
||
export interface ISearchResponse extends IResponse { | ||
/** | ||
* Block if it was found. | ||
*/ | ||
block?: Block; | ||
|
||
/** | ||
* Address details. | ||
*/ | ||
addressDetails?: IAddressDetails; | ||
|
||
/** | ||
* Output if it was found (block will also be populated). | ||
*/ | ||
output?: OutputResponse; | ||
|
||
/** | ||
* Account id if it was found. | ||
*/ | ||
accountId?: string; | ||
|
||
/** | ||
* Anchor id if it was found. | ||
*/ | ||
anchorId?: string; | ||
|
||
/** | ||
* Foundry id if it was found. | ||
*/ | ||
foundryId?: string; | ||
|
||
/** | ||
* Nft id if it was found. | ||
*/ | ||
nftId?: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { ServiceFactory } from "../../factories/serviceFactory"; | ||
import { ISearchRequest } from "../../models/api/nova/ISearchRequest"; | ||
import { ISearchResponse } from "../../models/api/nova/ISearchResponse"; | ||
import { IConfiguration } from "../../models/configuration/IConfiguration"; | ||
import { NOVA } from "../../models/db/protocolVersion"; | ||
import { NetworkService } from "../../services/networkService"; | ||
import { NovaApiService } from "../../services/nova/novaApiService"; | ||
import { ValidationHelper } from "../../utils/validationHelper"; | ||
|
||
/** | ||
* Find the object from the network. | ||
* @param _ The configuration. | ||
* @param request The request. | ||
* @returns The response. | ||
*/ | ||
export async function search(_: IConfiguration, request: ISearchRequest): Promise<ISearchResponse> { | ||
const networkService = ServiceFactory.get<NetworkService>("network"); | ||
const networks = networkService.networkNames(); | ||
ValidationHelper.oneOf(request.network, networks, "network"); | ||
ValidationHelper.string(request.query, "query"); | ||
|
||
const networkConfig = networkService.get(request.network); | ||
|
||
if (networkConfig.protocolVersion !== NOVA) { | ||
return {}; | ||
} | ||
|
||
const novaApiService = ServiceFactory.get<NovaApiService>(`api-service-${networkConfig.network}`); | ||
return novaApiService.search(request.query); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
/* eslint-disable import/no-unresolved */ | ||
/* eslint-disable @typescript-eslint/no-redundant-type-constituents */ | ||
/* eslint-disable @typescript-eslint/no-unsafe-argument */ | ||
import { | ||
Address, | ||
AddressType, | ||
AccountAddress, | ||
Ed25519Address, | ||
NftAddress, | ||
AnchorAddress, | ||
Utils, | ||
ImplicitAccountCreationAddress, | ||
RestrictedAddress, | ||
} from "@iota/sdk-nova"; | ||
import { plainToInstance } from "class-transformer"; | ||
import { IAddressDetails } from "../../models/api/nova/IAddressDetails"; | ||
import { HexHelper } from "../hexHelper"; | ||
|
||
export class AddressHelper { | ||
/** | ||
* Build the address details. | ||
* @param hrp The human readable part of the address. | ||
* @param address The address to source the data from. | ||
* @param typeHint The type of the address. | ||
* @returns The parts of the address. | ||
*/ | ||
public static buildAddress(hrp: string, address: string | Address, typeHint?: number): IAddressDetails { | ||
return typeof address === "string" ? this.buildAddressFromString(hrp, address, typeHint) : this.buildAddressFromTypes(address, hrp); | ||
} | ||
|
||
private static buildAddressFromString(hrp: string, addressString: string, typeHint?: number): IAddressDetails { | ||
let bech32: string; | ||
let hex: string; | ||
let type: AddressType; | ||
if (Utils.isAddressValid(addressString)) { | ||
try { | ||
const address: Address = Utils.parseBech32Address(addressString); | ||
|
||
if (address) { | ||
bech32 = addressString; | ||
type = address.type; | ||
hex = Utils.bech32ToHex(addressString); | ||
} | ||
} catch (e) { | ||
console.error(e); | ||
} | ||
} | ||
|
||
if (!bech32) { | ||
// We assume this is hex | ||
hex = addressString; | ||
if (typeHint) { | ||
bech32 = this.computeBech32FromHexAndType(hex, type, hrp); | ||
} | ||
} | ||
|
||
return { | ||
bech32, | ||
hex: hex ? HexHelper.addPrefix(hex) : hex, | ||
type, | ||
label: AddressHelper.typeLabel(type), | ||
restricted: false, | ||
}; | ||
} | ||
|
||
private static buildAddressFromTypes( | ||
address: Address, | ||
hrp: string, | ||
restricted: boolean = false, | ||
capabilities?: number[], | ||
): IAddressDetails { | ||
let hex: string = ""; | ||
let bech32: string = ""; | ||
|
||
if (address.type === AddressType.Ed25519) { | ||
hex = (address as Ed25519Address).pubKeyHash; | ||
} else if (address.type === AddressType.Account) { | ||
hex = (address as AccountAddress).accountId; | ||
} else if (address.type === AddressType.Nft) { | ||
hex = (address as NftAddress).nftId; | ||
} else if (address.type === AddressType.Anchor) { | ||
hex = (address as AnchorAddress).anchorId; | ||
} else if (address.type === AddressType.ImplicitAccountCreation) { | ||
const implicitAccountCreationAddress = plainToInstance(ImplicitAccountCreationAddress, address); | ||
const innerAddress = implicitAccountCreationAddress.address(); | ||
hex = innerAddress.pubKeyHash; | ||
} else if (address.type === AddressType.Restricted) { | ||
const restrictedAddress = plainToInstance(RestrictedAddress, address); | ||
const innerAddress = restrictedAddress.address; | ||
|
||
return this.buildAddressFromTypes( | ||
innerAddress, | ||
hrp, | ||
true, | ||
Array.from(restrictedAddress.getAllowedCapabilities() as ArrayLike<number>), | ||
); | ||
} | ||
|
||
bech32 = this.computeBech32FromHexAndType(hex, address.type, hrp); | ||
|
||
return { | ||
bech32, | ||
hex, | ||
type: address.type, | ||
label: AddressHelper.typeLabel(address.type), | ||
restricted, | ||
capabilities, | ||
}; | ||
} | ||
|
||
private static computeBech32FromHexAndType(hex: string, addressType: AddressType, hrp: string) { | ||
let bech32 = ""; | ||
|
||
if (addressType === AddressType.Ed25519) { | ||
bech32 = Utils.hexToBech32(hex, hrp); | ||
} else if (addressType === AddressType.Account) { | ||
bech32 = Utils.accountIdToBech32(hex, hrp); | ||
} else if (addressType === AddressType.Nft) { | ||
bech32 = Utils.nftIdToBech32(hex, hrp); | ||
} else if (addressType === AddressType.Anchor) { | ||
// Update to Utils.anchorIdToBech32 when it gets implemented | ||
bech32 = Utils.accountIdToBech32(hex, hrp); | ||
} else if (addressType === AddressType.ImplicitAccountCreation) { | ||
bech32 = Utils.hexToBech32(hex, hrp); | ||
} | ||
|
||
return bech32; | ||
} | ||
|
||
/** | ||
* Convert the address type number to a label. | ||
* @param addressType The address type to get the label for. | ||
* @returns The label. | ||
*/ | ||
private static typeLabel(addressType?: AddressType): string | undefined { | ||
if (addressType === AddressType.Ed25519) { | ||
return "Ed25519"; | ||
} else if (addressType === AddressType.Account) { | ||
return "Account"; | ||
} else if (addressType === AddressType.Nft) { | ||
return "NFT"; | ||
} else if (addressType === AddressType.Anchor) { | ||
return "Anchor"; | ||
} | ||
} | ||
} |
Oops, something went wrong.