mirror of
https://github.com/Qortal/Q-Apps-Utils.git
synced 2025-01-30 14:52:18 +00:00
Major updates to many files.
This commit is contained in:
parent
1ffbd743c5
commit
715a25e582
2
index.d.ts
vendored
2
index.d.ts
vendored
@ -10,7 +10,7 @@ export * from "./dist/src/QortalRequest/Utils/Types";
|
|||||||
|
|
||||||
export * from "./dist/src/QortalRequest/getFromAddress";
|
export * from "./dist/src/QortalRequest/getFromAddress";
|
||||||
export * from "./dist/src/QortalRequest/getFromSelf";
|
export * from "./dist/src/QortalRequest/getFromSelf";
|
||||||
export * from "./dist/src/QortalRequest/setFromSelf";
|
export * from "./dist/src/QortalRequest/profile";
|
||||||
export * from "./dist/src/QortalRequest/SendCoin";
|
export * from "./dist/src/QortalRequest/SendCoin";
|
||||||
export * from "./dist/src/QortalRequest/Transactions";
|
export * from "./dist/src/QortalRequest/Transactions";
|
||||||
export * from "./dist/src/QortalRequest/general"
|
export * from "./dist/src/QortalRequest/general"
|
12
index.ts
12
index.ts
@ -1,8 +1,8 @@
|
|||||||
export * from "./src/TypescriptUtils/Numbers/Colors";
|
export * from "./src/Utils/Numbers/Colors";
|
||||||
export * from "./src/TypescriptUtils/Numbers/NumberConversion";
|
export * from "./src/Utils/Numbers/NumberConversion";
|
||||||
export * from "./src/TypescriptUtils/Numbers/Numbers";
|
export * from "./src/Utils/Numbers/Numbers";
|
||||||
export * from "./src/TypescriptUtils/Numbers/StringNumbers";
|
export * from "./src/Utils/Numbers/StringNumbers";
|
||||||
export * from "./src/TypescriptUtils/Strings/printFunctions";
|
export * from "./src/Utils/Strings/printFunctions";
|
||||||
|
|
||||||
export * from "./src/QortalRequest/Utils/Interfaces/Responses";
|
export * from "./src/QortalRequest/Utils/Interfaces/Responses";
|
||||||
export * from "./src/QortalRequest/Utils/Interfaces/Parameters";
|
export * from "./src/QortalRequest/Utils/Interfaces/Parameters";
|
||||||
@ -10,7 +10,7 @@ export * from "./src/QortalRequest/Utils/Types";
|
|||||||
|
|
||||||
export * from "./src/QortalRequest/getFromAddress";
|
export * from "./src/QortalRequest/getFromAddress";
|
||||||
export * from "./src/QortalRequest/getFromSelf";
|
export * from "./src/QortalRequest/getFromSelf";
|
||||||
export * from "./src/QortalRequest/setFromSelf";
|
export * from "./src/QortalRequest/profile";
|
||||||
export * from "./src/QortalRequest/SendCoin";
|
export * from "./src/QortalRequest/SendCoin";
|
||||||
export * from "./src/QortalRequest/Transactions";
|
export * from "./src/QortalRequest/Transactions";
|
||||||
export * from "./src/QortalRequest/general";
|
export * from "./src/QortalRequest/general";
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "qortal-app-utils",
|
"name": "qortal-app-utils",
|
||||||
"version": "1.4.0",
|
"version": "1.5.0",
|
||||||
"description": "A series of convenience functions that perform common tasks, especially those that interact with the Qortal blockchain",
|
"description": "A series of convenience functions that perform common tasks, especially those that interact with the Qortal blockchain",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Qortal",
|
"Qortal",
|
||||||
|
51
src/QortalRequest/Profile.ts
Normal file
51
src/QortalRequest/Profile.ts
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// returns {error: "Cannot find requested data"} if data isn't found
|
||||||
|
import { ProfileCoinType } from "./Utils/Types.ts";
|
||||||
|
|
||||||
|
export const getProfileData = async (property: string) => {
|
||||||
|
return (await qortalRequest({
|
||||||
|
action: "GET_PROFILE_DATA",
|
||||||
|
property,
|
||||||
|
})) as string | object;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setProfileData = async (
|
||||||
|
property: string,
|
||||||
|
data: object,
|
||||||
|
encrypt = false
|
||||||
|
) => {
|
||||||
|
if (encrypt) property += "-private";
|
||||||
|
return (await qortalRequest({
|
||||||
|
action: "SET_PROFILE_DATA",
|
||||||
|
property,
|
||||||
|
data: { customData: data },
|
||||||
|
})) as string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setDefaultProfileData = async (
|
||||||
|
property: string,
|
||||||
|
data: object,
|
||||||
|
encrypt = false
|
||||||
|
) => {
|
||||||
|
if (encrypt) property += "-private";
|
||||||
|
return (await qortalRequest({
|
||||||
|
action: "SET_PROFILE_DATA",
|
||||||
|
property,
|
||||||
|
data,
|
||||||
|
})) as string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getProfileWallet = async (coin: ProfileCoinType) => {
|
||||||
|
return await getProfileData("wallets")[coin];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const setProfileWallet = async (wallet: object) => {
|
||||||
|
return await setProfileData("wallets", wallet);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const summonProfileModal = async () => {
|
||||||
|
return (await qortalRequest({
|
||||||
|
action: "SET_PROFILE_DATA",
|
||||||
|
property: "wallets",
|
||||||
|
data: {},
|
||||||
|
})) as string;
|
||||||
|
};
|
62
src/QortalRequest/Qapps/Qfund.ts
Normal file
62
src/QortalRequest/Qapps/Qfund.ts
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
export const hasQFundEnded = async (atAddress: string) => {
|
||||||
|
try {
|
||||||
|
const url = `/at/${atAddress}`;
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (response.status === 200) {
|
||||||
|
const responseDataSearch = await response.json();
|
||||||
|
if (
|
||||||
|
Object.keys(responseDataSearch).length > 0 &&
|
||||||
|
responseDataSearch?.isFinished
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getATAmount = async crowdfundLink => {
|
||||||
|
const crowdfund = await getCrowdfund(crowdfundLink);
|
||||||
|
const atAddress = crowdfund?.deployedAT?.aTAddress;
|
||||||
|
if (!atAddress) return 0;
|
||||||
|
try {
|
||||||
|
const res = await qortalRequest({
|
||||||
|
action: "SEARCH_TRANSACTIONS",
|
||||||
|
txType: ["PAYMENT"],
|
||||||
|
confirmationStatus: "CONFIRMED",
|
||||||
|
address: atAddress,
|
||||||
|
limit: 0,
|
||||||
|
reverse: true,
|
||||||
|
});
|
||||||
|
if (res?.length > 0) {
|
||||||
|
const totalAmount: number = res.reduce(
|
||||||
|
(total: number, transaction) => total + parseFloat(transaction.amount),
|
||||||
|
0
|
||||||
|
);
|
||||||
|
return totalAmount;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getCrowdfund = async (crowdfundLink: string) => {
|
||||||
|
const splitLink = crowdfundLink.split("/");
|
||||||
|
const name = splitLink[5];
|
||||||
|
const identifier = splitLink[6];
|
||||||
|
return await qortalRequest({
|
||||||
|
action: "FETCH_QDN_RESOURCE",
|
||||||
|
service: "DOCUMENT",
|
||||||
|
name,
|
||||||
|
identifier,
|
||||||
|
});
|
||||||
|
};
|
28
src/QortalRequest/Search.ts
Normal file
28
src/QortalRequest/Search.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { SearchResourcesResponse } from "./Utils/Interfaces/Responses.ts";
|
||||||
|
|
||||||
|
export const fetchResourcesByIdentifier = async <T>(
|
||||||
|
service: string,
|
||||||
|
identifier: string
|
||||||
|
) => {
|
||||||
|
const names: SearchResourcesResponse[] = await qortalRequest({
|
||||||
|
action: "SEARCH_QDN_RESOURCES",
|
||||||
|
service,
|
||||||
|
identifier,
|
||||||
|
includeMetadata: false,
|
||||||
|
});
|
||||||
|
const distinctNames = names.filter(
|
||||||
|
(searchResponse, index) => names.indexOf(searchResponse) === index
|
||||||
|
);
|
||||||
|
|
||||||
|
const promises: Promise<T>[] = [];
|
||||||
|
distinctNames.map(response => {
|
||||||
|
const resource: Promise<T> = qortalRequest({
|
||||||
|
action: "FETCH_QDN_RESOURCE",
|
||||||
|
name: response.name,
|
||||||
|
service,
|
||||||
|
identifier,
|
||||||
|
});
|
||||||
|
promises.push(resource);
|
||||||
|
});
|
||||||
|
return (await Promise.all(promises)) as T[];
|
||||||
|
};
|
@ -1,22 +1,48 @@
|
|||||||
import { CoinType } from "./Utils/Types";
|
import { CoinType } from "./Utils/Types";
|
||||||
|
import { SendCoinResponse } from "./Utils/Interfaces/Responses.ts";
|
||||||
|
|
||||||
export const sendCoin = async (
|
export const sendCoin = async (
|
||||||
address: string,
|
address: string,
|
||||||
amount: number,
|
amount: number,
|
||||||
coin: CoinType
|
coin: CoinType
|
||||||
) => {
|
) => {
|
||||||
return qortalRequest({
|
try {
|
||||||
action: "SEND_COIN",
|
return (await qortalRequest({
|
||||||
coin,
|
action: "SEND_COIN",
|
||||||
destinationAddress: address,
|
coin,
|
||||||
amount,
|
destinationAddress: address,
|
||||||
});
|
amount,
|
||||||
|
})) as SendCoinResponse;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("sendCoin refused", e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sendQORT = async (address: string, amount: number) => {
|
export const sendQORT = async (address: string, amount: number) => {
|
||||||
return await sendCoin(address, amount, "QORT");
|
return await sendCoin(address, amount, "QORT");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export interface NameData {
|
||||||
|
name: string;
|
||||||
|
reducedName: string;
|
||||||
|
owner: string;
|
||||||
|
data: string;
|
||||||
|
registered: number;
|
||||||
|
isForSale: boolean;
|
||||||
|
}
|
||||||
|
export const getNameData = async (name: string) => {
|
||||||
|
return qortalRequest({
|
||||||
|
action: "GET_NAME_DATA",
|
||||||
|
name: name,
|
||||||
|
}) as Promise<NameData>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendQORTtoName = async (name: string, amount: number) => {
|
||||||
|
const address = await getNameData(name);
|
||||||
|
if (address) return await sendQORT(address.owner, amount);
|
||||||
|
else throw Error("Name Not Found");
|
||||||
|
};
|
||||||
|
|
||||||
export const sendBitCoin = async (address: string, amount: number) => {
|
export const sendBitCoin = async (address: string, amount: number) => {
|
||||||
return await sendCoin(address, amount, "BTC");
|
return await sendCoin(address, amount, "BTC");
|
||||||
};
|
};
|
||||||
|
@ -33,3 +33,32 @@ export interface DaySummaryResponse {
|
|||||||
totalTransactionCount: number;
|
totalTransactionCount: number;
|
||||||
transactionCountByType: SummaryTransactionCounts;
|
transactionCountByType: SummaryTransactionCounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MetaData {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
tags: string[];
|
||||||
|
mimeType: string;
|
||||||
|
}
|
||||||
|
export interface SearchResourcesResponse {
|
||||||
|
name: string;
|
||||||
|
service: string;
|
||||||
|
identifier: string;
|
||||||
|
metadata?: MetaData;
|
||||||
|
size: number;
|
||||||
|
created: number;
|
||||||
|
updated: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SendCoinResponse {
|
||||||
|
amount: number;
|
||||||
|
approvalStatus: string;
|
||||||
|
fee: string;
|
||||||
|
recipient: string;
|
||||||
|
reference: string;
|
||||||
|
senderPublicKey: string;
|
||||||
|
signature: string;
|
||||||
|
timestamp: number;
|
||||||
|
txGroupId: number;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
@ -42,12 +42,18 @@ export type TransactionType =
|
|||||||
| "TRANSFER_PRIVS"
|
| "TRANSFER_PRIVS"
|
||||||
| "PRESENCE";
|
| "PRESENCE";
|
||||||
|
|
||||||
export type CoinType = "QORT" | "BTC" | "LTC" | "DOGE" | "DGB" | "RVN" | "ARRR";
|
export const Coins = ["QORT", "BTC", "LTC", "DOGE", "DGB", "RVN", "ARRR"];
|
||||||
|
export type CoinType = (typeof Coins)[number];
|
||||||
|
|
||||||
export type BlockchainType =
|
export const ProfileCoins = ["btc", "ltc", "doge", "dgb", "rvn", "arrr"];
|
||||||
| "BITCOIN"
|
export type ProfileCoinType = (typeof ProfileCoins)[number];
|
||||||
| "LITECOIN"
|
export const Blockchains = [
|
||||||
| "DODGECOIN"
|
"BITCOIN",
|
||||||
| "DIGIBYTE"
|
"LITECOIN",
|
||||||
| "RAVENCOIN"
|
"DOGECOIN",
|
||||||
| "PIRATECHAIN";
|
"DIGIBYTE",
|
||||||
|
"RAVENCOIN",
|
||||||
|
"PIRATECHAIN",
|
||||||
|
];
|
||||||
|
|
||||||
|
export type BlockchainType = (typeof Blockchains)[number];
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { DaySummaryResponse } from "./Utils/Interfaces/Responses.ts";
|
import { DaySummaryResponse } from "./Utils/Interfaces/Responses.ts";
|
||||||
import { BlockchainType } from "./Utils/Types.ts";
|
import { Blockchains, BlockchainType } from "./Utils/Types.ts";
|
||||||
import { truncateNumber } from "../TypescriptUtils/Numbers/StringNumbers.ts";
|
import { truncateNumber } from "../Utils/Numbers/StringNumbers.ts";
|
||||||
|
import { getNameData } from "./SendCoin.ts";
|
||||||
|
import { getUserAccountNames } from "./getFromSelf.ts";
|
||||||
|
|
||||||
export const getDaySummary = async () => {
|
export const getDaySummary = async () => {
|
||||||
return (await qortalRequest({
|
return (await qortalRequest({
|
||||||
@ -32,16 +34,59 @@ export const getDurationFromBlocks = async (blocks: number) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPrice = async (
|
export const getPriceAsNumber = async (
|
||||||
blockchainName: BlockchainType,
|
blockchainName: BlockchainType,
|
||||||
tradesToInclude = 10,
|
tradesToInclude = 10
|
||||||
isQortRatio = true
|
|
||||||
) => {
|
) => {
|
||||||
const response = (await qortalRequest({
|
const response = (await qortalRequest({
|
||||||
action: "GET_PRICE",
|
action: "GET_PRICE",
|
||||||
blockchain: blockchainName,
|
blockchain: blockchainName,
|
||||||
maxTrades: tradesToInclude,
|
maxTrades: tradesToInclude,
|
||||||
inverse: isQortRatio,
|
inverse: true,
|
||||||
})) as number;
|
})) as number;
|
||||||
return response / 1e8;
|
return response / 1e8;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type BlockchainPrice = { name: BlockchainType; price: number };
|
||||||
|
|
||||||
|
const getPriceAsObject = async (
|
||||||
|
chain: BlockchainType,
|
||||||
|
tradesToInclude: number
|
||||||
|
) => {
|
||||||
|
return { name: chain, price: await getPriceAsNumber(chain, tradesToInclude) };
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getPricesAsObject = async (
|
||||||
|
chains: BlockchainType[],
|
||||||
|
tradesToInclude = 10
|
||||||
|
) => {
|
||||||
|
return await Promise.all(
|
||||||
|
chains.map(async (chain: BlockchainType) => {
|
||||||
|
return getPriceAsObject(chain, tradesToInclude);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const sendQchatDM = async (
|
||||||
|
recipientName: string,
|
||||||
|
message: string,
|
||||||
|
allowSelfAsRecipient = false
|
||||||
|
) => {
|
||||||
|
if (!allowSelfAsRecipient) {
|
||||||
|
const userAccountNames = await getUserAccountNames();
|
||||||
|
const userNames = userAccountNames.map(name => name.name);
|
||||||
|
if (userNames.includes(recipientName)) return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const address = await getNameData(recipientName);
|
||||||
|
try {
|
||||||
|
return await qortalRequest({
|
||||||
|
action: "SEND_CHAT_MESSAGE",
|
||||||
|
destinationAddress: address.owner,
|
||||||
|
message,
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { stringIsEmpty } from "../TypescriptUtils/Numbers/StringNumbers";
|
import { stringIsEmpty } from "../Utils/Numbers/StringNumbers";
|
||||||
import { GetRequestData } from "./Utils/Interfaces/Parameters.ts";
|
import { GetRequestData } from "./Utils/Interfaces/Parameters.ts";
|
||||||
type AccountName = { name: string; owner: string };
|
type AccountName = { name: string; owner: string };
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ export const getAccountNames = async (
|
|||||||
) => {
|
) => {
|
||||||
const names = (await qortalRequest({
|
const names = (await qortalRequest({
|
||||||
action: "GET_ACCOUNT_NAMES",
|
action: "GET_ACCOUNT_NAMES",
|
||||||
address,
|
address: address,
|
||||||
...params,
|
...params,
|
||||||
})) as AccountName[];
|
})) as AccountName[];
|
||||||
|
|
||||||
|
8
src/QortalRequest/getFromName.ts
Normal file
8
src/QortalRequest/getFromName.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export const getAvatarFromName = async (name: string) => {
|
||||||
|
return await qortalRequest({
|
||||||
|
action: "GET_QDN_RESOURCE_URL",
|
||||||
|
name,
|
||||||
|
service: "THUMBNAIL",
|
||||||
|
identifier: "qortal_avatar",
|
||||||
|
});
|
||||||
|
};
|
@ -1,5 +1,6 @@
|
|||||||
import { getBalance } from "./getFromAddress";
|
import { getBalance } from "./getFromAddress";
|
||||||
import { CoinType } from "./Utils/Types";
|
import { CoinType } from "./Utils/Types";
|
||||||
|
import { GetRequestData } from "./Utils/Interfaces/Parameters.ts";
|
||||||
|
|
||||||
export const getWalletBalance = async (coin: CoinType) => {
|
export const getWalletBalance = async (coin: CoinType) => {
|
||||||
return (await qortalRequest({
|
return (await qortalRequest({
|
||||||
@ -21,16 +22,45 @@ export const getForeignWallet = async (coin: CoinType) => {
|
|||||||
coin,
|
coin,
|
||||||
})) as AccountInfo;
|
})) as AccountInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const stringIsEmpty = (value: string) => {
|
||||||
|
return value === "";
|
||||||
|
};
|
||||||
|
|
||||||
|
export type AccountName = { name: string; owner: string };
|
||||||
|
export const getAccountNames = async (
|
||||||
|
address: string,
|
||||||
|
params?: GetRequestData
|
||||||
|
) => {
|
||||||
|
const names = (await qortalRequest({
|
||||||
|
action: "GET_ACCOUNT_NAMES",
|
||||||
|
address: address,
|
||||||
|
...params,
|
||||||
|
})) as AccountName[];
|
||||||
|
|
||||||
|
const namelessAddress = { name: "", owner: address };
|
||||||
|
const emptyNamesFilled = names.map(({ name, owner }) => {
|
||||||
|
return stringIsEmpty(name) ? namelessAddress : { name, owner };
|
||||||
|
});
|
||||||
|
|
||||||
|
const returnValue =
|
||||||
|
emptyNamesFilled.length > 0 ? emptyNamesFilled : [namelessAddress];
|
||||||
|
return returnValue as AccountName[];
|
||||||
|
};
|
||||||
|
|
||||||
export const getUserAccount = async () => {
|
export const getUserAccount = async () => {
|
||||||
return (await qortalRequest({
|
return (await qortalRequest({
|
||||||
action: "GET_USER_ACCOUNT",
|
action: "GET_USER_ACCOUNT",
|
||||||
})) as AccountInfo;
|
})) as AccountInfo;
|
||||||
};
|
};
|
||||||
|
|
||||||
// returns {error: "Cannot find requested data"} if data isn't found
|
export const getUserAccountNames = async () => {
|
||||||
export const getProfileData = async (property: string) => {
|
const account = await getUserAccount();
|
||||||
return (await qortalRequest({
|
return await getAccountNames(account.address);
|
||||||
action: "GET_PROFILE_DATA",
|
};
|
||||||
property,
|
|
||||||
})) as string | object;
|
export const userHasName = async (name: string) => {
|
||||||
|
const userAccountNames = await getUserAccountNames();
|
||||||
|
const userNames = userAccountNames.map(userName => userName.name);
|
||||||
|
return userNames.includes(name);
|
||||||
};
|
};
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
export const setProfileData = async (
|
|
||||||
property: string,
|
|
||||||
data: object,
|
|
||||||
encrypt = false
|
|
||||||
) => {
|
|
||||||
if (encrypt) property += "-private";
|
|
||||||
return (await qortalRequest({
|
|
||||||
action: "SET_PROFILE_DATA",
|
|
||||||
property,
|
|
||||||
data: { customData: data },
|
|
||||||
})) as string;
|
|
||||||
};
|
|
@ -7,3 +7,7 @@ export const setNumberWithinBounds = (
|
|||||||
if (num < minValue) return minValue;
|
if (num < minValue) return minValue;
|
||||||
return num;
|
return num;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const numberToInt = (num: number) => {
|
||||||
|
return Math.floor(num);
|
||||||
|
};
|
184
src/Utils/PublishFormatter.ts
Normal file
184
src/Utils/PublishFormatter.ts
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
export const publishFormatter = (
|
||||||
|
file: File
|
||||||
|
): Promise<string | ArrayBuffer | null> =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
|
||||||
|
reader.onload = () => {
|
||||||
|
const result = reader.result;
|
||||||
|
reader.onload = null; // remove onload handler
|
||||||
|
reader.onerror = null; // remove onerror handler
|
||||||
|
resolve(result);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.onerror = error => {
|
||||||
|
reader.onload = null; // remove onload handler
|
||||||
|
reader.onerror = null; // remove onerror handler
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
export function objectToBase64(obj: any) {
|
||||||
|
// Step 1: Convert the object to a JSON string
|
||||||
|
const jsonString = JSON.stringify(obj);
|
||||||
|
|
||||||
|
// Step 2: Create a Blob from the JSON string
|
||||||
|
const blob = new Blob([jsonString], { type: "application/json" });
|
||||||
|
|
||||||
|
// Step 3: Create a FileReader to read the Blob as a base64-encoded string
|
||||||
|
return new Promise<string>((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onloadend = () => {
|
||||||
|
if (typeof reader.result === "string") {
|
||||||
|
// Remove 'data:application/json;base64,' prefix
|
||||||
|
const base64 = reader.result.replace(
|
||||||
|
"data:application/json;base64,",
|
||||||
|
""
|
||||||
|
);
|
||||||
|
resolve(base64);
|
||||||
|
} else {
|
||||||
|
reject(new Error("Failed to read the Blob as a base64-encoded string"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
reader.onerror = () => {
|
||||||
|
reject(reader.error);
|
||||||
|
};
|
||||||
|
reader.readAsDataURL(blob);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function objectToFile(obj: any) {
|
||||||
|
// Step 1: Convert the object to a JSON string
|
||||||
|
const jsonString = JSON.stringify(obj);
|
||||||
|
|
||||||
|
// Step 2: Create a Blob from the JSON string
|
||||||
|
return new Blob([jsonString], { type: "application/json" });
|
||||||
|
}
|
||||||
|
|
||||||
|
export function objectToUint8Array(obj: any) {
|
||||||
|
// Convert the object to a JSON string
|
||||||
|
const jsonString = JSON.stringify(obj);
|
||||||
|
|
||||||
|
// Encode the JSON string as a byte array using TextEncoder
|
||||||
|
const encoder = new TextEncoder();
|
||||||
|
const byteArray = encoder.encode(jsonString);
|
||||||
|
|
||||||
|
// Create a new Uint8Array and set its content to the encoded byte array
|
||||||
|
const uint8Array = new Uint8Array(byteArray);
|
||||||
|
|
||||||
|
return uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function uint8ArrayToBase64(uint8Array: Uint8Array): string {
|
||||||
|
const length = uint8Array.length;
|
||||||
|
let binaryString = "";
|
||||||
|
const chunkSize = 1024 * 1024; // Process 1MB at a time
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i += chunkSize) {
|
||||||
|
const chunkEnd = Math.min(i + chunkSize, length);
|
||||||
|
const chunk = uint8Array.subarray(i, chunkEnd);
|
||||||
|
binaryString += Array.from(chunk, byte => String.fromCharCode(byte)).join(
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return btoa(binaryString);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function objectToUint8ArrayFromResponse(obj: any) {
|
||||||
|
const len = Object.keys(obj).length;
|
||||||
|
const result = new Uint8Array(len);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
result[i] = obj[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
// export function uint8ArrayToBase64(arrayBuffer: Uint8Array): string {
|
||||||
|
// let binary = ''
|
||||||
|
// const bytes = new Uint8Array(arrayBuffer)
|
||||||
|
// const len = bytes.length
|
||||||
|
|
||||||
|
// for (let i = 0; i < len; i++) {
|
||||||
|
// binary += String.fromCharCode(bytes[i])
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return btoa(binary)
|
||||||
|
// }
|
||||||
|
|
||||||
|
export function base64ToUint8Array(base64: string) {
|
||||||
|
const binaryString = atob(base64);
|
||||||
|
const len = binaryString.length;
|
||||||
|
const bytes = new Uint8Array(len);
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = binaryString.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function uint8ArrayToObject(uint8Array: Uint8Array) {
|
||||||
|
// Decode the byte array using TextDecoder
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
const jsonString = decoder.decode(uint8Array);
|
||||||
|
|
||||||
|
// Convert the JSON string back into an object
|
||||||
|
const obj = JSON.parse(jsonString);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function processFileInChunks(file: File): Promise<Uint8Array> {
|
||||||
|
return new Promise(
|
||||||
|
(resolve: (value: Uint8Array) => void, reject: (reason?: any) => void) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = function (event: ProgressEvent<FileReader>) {
|
||||||
|
const arrayBuffer = event.target?.result as ArrayBuffer;
|
||||||
|
const uint8Array = new Uint8Array(arrayBuffer);
|
||||||
|
resolve(uint8Array);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.onerror = function (error: ProgressEvent<FileReader>) {
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsArrayBuffer(file);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// export async function processFileInChunks(file: File, chunkSize = 1024 * 1024): Promise<Uint8Array> {
|
||||||
|
// const fileStream = file.stream();
|
||||||
|
// const reader = fileStream.getReader();
|
||||||
|
// const totalLength = file.size;
|
||||||
|
|
||||||
|
// if (totalLength <= 0 || isNaN(totalLength)) {
|
||||||
|
// throw new Error('Invalid file size');
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const combinedArray = new Uint8Array(totalLength);
|
||||||
|
// let offset = 0;
|
||||||
|
|
||||||
|
// while (offset < totalLength) {
|
||||||
|
// const { value, done } = await reader.read();
|
||||||
|
|
||||||
|
// if (done) {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const chunk = new Uint8Array(value.buffer, value.byteOffset, value.byteLength);
|
||||||
|
|
||||||
|
// // Set elements one by one instead of using combinedArray.set(chunk, offset)
|
||||||
|
// for (let i = 0; i < chunk.length; i++) {
|
||||||
|
// combinedArray[offset + i] = chunk[i];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// offset += chunk.length;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return combinedArray;
|
||||||
|
// }
|
13
src/Utils/Strings/stringFunctions.ts
Normal file
13
src/Utils/Strings/stringFunctions.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export const getFileExtensionIndex = (s: string) => {
|
||||||
|
const lastIndex = s.lastIndexOf(".");
|
||||||
|
return lastIndex > 0 ? lastIndex : s.length - 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getFileName = (s: string) => {
|
||||||
|
return s.substring(0, getFileExtensionIndex(s));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const isNumber = (input: string) => {
|
||||||
|
const num = Number(input);
|
||||||
|
return !isNaN(num);
|
||||||
|
};
|
3
src/global.d.ts
vendored
3
src/global.d.ts
vendored
@ -99,6 +99,7 @@ interface QortalRequestOptions {
|
|||||||
maxTrades?: number;
|
maxTrades?: number;
|
||||||
inverse?: boolean;
|
inverse?: boolean;
|
||||||
property?: string;
|
property?: string;
|
||||||
data?: { customData: object };
|
data?: { customData?: object };
|
||||||
|
message?: string;
|
||||||
}
|
}
|
||||||
declare function qortalRequest(options: QortalRequestOptions): Promise<any>;
|
declare function qortalRequest(options: QortalRequestOptions): Promise<any>;
|
||||||
|
Loading…
Reference in New Issue
Block a user