Linkify engine error codes and some refactor.
This commit is contained in:
@@ -6,14 +6,15 @@ import calculateHookOn, { TTS } from "../../utils/hookOnCalculator";
|
||||
import { Link } from "../../components";
|
||||
import { ref } from "valtio";
|
||||
import estimateFee from "../../utils/estimateFee";
|
||||
import { SetHookData } from '../../utils/setHook';
|
||||
import { SetHookData } from "../../utils/setHook";
|
||||
import ResultLink from "../../components/ResultLink";
|
||||
|
||||
export const sha256 = async (string: string) => {
|
||||
const utf8 = new TextEncoder().encode(string);
|
||||
const hashBuffer = await crypto.subtle.digest("SHA-256", utf8);
|
||||
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
||||
const hashHex = hashArray
|
||||
.map((bytes) => bytes.toString(16).padStart(2, "0"))
|
||||
.map(bytes => bytes.toString(16).padStart(2, "0"))
|
||||
.join("");
|
||||
return hashHex;
|
||||
};
|
||||
@@ -56,7 +57,7 @@ export const prepareDeployHookTx = async (
|
||||
) => {
|
||||
const activeFile = state.files[state.active]?.compiledContent
|
||||
? state.files[state.active]
|
||||
: state.files.filter((file) => file.compiledContent)[0];
|
||||
: state.files.filter(file => file.compiledContent)[0];
|
||||
|
||||
if (!state.files || state.files.length === 0) {
|
||||
return;
|
||||
@@ -69,12 +70,12 @@ export const prepareDeployHookTx = async (
|
||||
return;
|
||||
}
|
||||
const HookNamespace = (await sha256(data.HookNamespace)).toUpperCase();
|
||||
const hookOnValues: (keyof TTS)[] = data.Invoke.map((tt) => tt.value);
|
||||
const hookOnValues: (keyof TTS)[] = data.Invoke.map(tt => tt.value);
|
||||
const { HookParameters } = data;
|
||||
const filteredHookParameters = HookParameters.filter(
|
||||
(hp) =>
|
||||
hp =>
|
||||
hp.HookParameter.HookParameterName && hp.HookParameter.HookParameterValue
|
||||
)?.map((aa) => ({
|
||||
)?.map(aa => ({
|
||||
HookParameter: {
|
||||
HookParameterName: toHex(aa.HookParameter.HookParameterName || ""),
|
||||
HookParameterValue: aa.HookParameter.HookParameterValue || "",
|
||||
@@ -128,7 +129,7 @@ export const deployHook = async (
|
||||
if (typeof window !== "undefined") {
|
||||
const activeFile = state.files[state.active]?.compiledContent
|
||||
? state.files[state.active]
|
||||
: state.files.filter((file) => file.compiledContent)[0];
|
||||
: state.files.filter(file => file.compiledContent)[0];
|
||||
state.deployValues[activeFile.name] = data;
|
||||
const tx = await prepareDeployHookTx(account, data);
|
||||
if (!tx) {
|
||||
@@ -141,7 +142,7 @@ export const deployHook = async (
|
||||
|
||||
const { signedTransaction } = sign(tx, keypair);
|
||||
const currentAccount = state.accounts.find(
|
||||
(acc) => acc.address === account.address
|
||||
acc => acc.address === account.address
|
||||
);
|
||||
if (currentAccount) {
|
||||
currentAccount.isLoading = true;
|
||||
@@ -154,6 +155,26 @@ export const deployHook = async (
|
||||
tx_blob: signedTransaction,
|
||||
});
|
||||
|
||||
const txHash = submitRes.tx_json?.hash;
|
||||
const resultMsg = ref(
|
||||
<>
|
||||
[<ResultLink result={submitRes.engine_result} />]{" "}
|
||||
{submitRes.engine_result_message}{" "}
|
||||
{txHash && (
|
||||
<>
|
||||
Transaction hash:{" "}
|
||||
<Link
|
||||
as="a"
|
||||
href={`https://${process.env.NEXT_PUBLIC_EXPLORER_URL}/${txHash}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{txHash}
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
if (submitRes.engine_result === "tesSUCCESS") {
|
||||
state.deployLogs.push({
|
||||
type: "success",
|
||||
@@ -161,28 +182,17 @@ export const deployHook = async (
|
||||
});
|
||||
state.deployLogs.push({
|
||||
type: "success",
|
||||
message: ref(
|
||||
<>
|
||||
[{submitRes.engine_result}] {submitRes.engine_result_message}{" "}
|
||||
Transaction hash:{" "}
|
||||
<Link
|
||||
as="a"
|
||||
href={`https://${process.env.NEXT_PUBLIC_EXPLORER_URL}/${submitRes.tx_json?.hash}`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
{submitRes.tx_json?.hash}
|
||||
</Link>
|
||||
</>
|
||||
),
|
||||
// message: `[${submitRes.engine_result}] ${submitRes.engine_result_message} Validated ledger index: ${submitRes.validated_ledger_index}`,
|
||||
message: resultMsg,
|
||||
});
|
||||
} else if (submitRes.engine_result) {
|
||||
state.deployLogs.push({
|
||||
type: "error",
|
||||
message: resultMsg,
|
||||
});
|
||||
} else {
|
||||
state.deployLogs.push({
|
||||
type: "error",
|
||||
message: `[${submitRes.engine_result || submitRes.error}] ${
|
||||
submitRes.engine_result_message || submitRes.error_exception
|
||||
}`,
|
||||
message: `[${submitRes.error}] ${submitRes.error_exception}`,
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -204,7 +214,7 @@ export const deleteHook = async (account: IAccount & { name?: string }) => {
|
||||
return;
|
||||
}
|
||||
const currentAccount = state.accounts.find(
|
||||
(acc) => acc.address === account.address
|
||||
acc => acc.address === account.address
|
||||
);
|
||||
if (currentAccount?.isLoading || !currentAccount?.hooks.length) {
|
||||
return;
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import { derive, sign } from "xrpl-accountlib";
|
||||
|
||||
import state from '..'
|
||||
import type { IAccount } from "..";
|
||||
|
||||
interface TransactionOptions {
|
||||
TransactionType: string,
|
||||
Account?: string,
|
||||
Fee?: string,
|
||||
Destination?: string
|
||||
[index: string]: any
|
||||
}
|
||||
interface OtherOptions {
|
||||
logPrefix?: string
|
||||
}
|
||||
|
||||
export const sendTransaction = async (account: IAccount, txOptions: TransactionOptions, options?: OtherOptions) => {
|
||||
if (!state.client) throw Error('XRPL client not initalized')
|
||||
|
||||
const { Fee = "1000", ...opts } = txOptions
|
||||
const tx: TransactionOptions = {
|
||||
Account: account.address,
|
||||
Sequence: account.sequence,
|
||||
Fee, // TODO auto-fillable default
|
||||
...opts
|
||||
};
|
||||
const { logPrefix = '' } = options || {}
|
||||
try {
|
||||
const signedAccount = derive.familySeed(account.secret);
|
||||
const { signedTransaction } = sign(tx, signedAccount);
|
||||
const response = await state.client.send({
|
||||
command: "submit",
|
||||
tx_blob: signedTransaction,
|
||||
});
|
||||
if (response.engine_result === "tesSUCCESS") {
|
||||
state.transactionLogs.push({
|
||||
type: 'success',
|
||||
message: `${logPrefix}[${response.engine_result}] ${response.engine_result_message}`
|
||||
})
|
||||
} else {
|
||||
state.transactionLogs.push({
|
||||
type: "error",
|
||||
message: `${logPrefix}[${response.error || response.engine_result}] ${response.error_exception || response.engine_result_message}`,
|
||||
});
|
||||
}
|
||||
const currAcc = state.accounts.find(acc => acc.address === account.address);
|
||||
if (currAcc && response.account_sequence_next) {
|
||||
currAcc.sequence = response.account_sequence_next;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
state.transactionLogs.push({
|
||||
type: "error",
|
||||
message: err instanceof Error ? `${logPrefix}Error: ${err.message}` : `${logPrefix}Something went wrong, try again later`,
|
||||
});
|
||||
}
|
||||
};
|
||||
78
state/actions/sendTransaction.tsx
Normal file
78
state/actions/sendTransaction.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import { derive, sign } from "xrpl-accountlib";
|
||||
|
||||
import state from "..";
|
||||
import type { IAccount } from "..";
|
||||
import ResultLink from "../../components/ResultLink";
|
||||
import { ref } from "valtio";
|
||||
|
||||
interface TransactionOptions {
|
||||
TransactionType: string;
|
||||
Account?: string;
|
||||
Fee?: string;
|
||||
Destination?: string;
|
||||
[index: string]: any;
|
||||
}
|
||||
interface OtherOptions {
|
||||
logPrefix?: string;
|
||||
}
|
||||
|
||||
export const sendTransaction = async (
|
||||
account: IAccount,
|
||||
txOptions: TransactionOptions,
|
||||
options?: OtherOptions
|
||||
) => {
|
||||
if (!state.client) throw Error("XRPL client not initalized");
|
||||
|
||||
const { Fee = "1000", ...opts } = txOptions;
|
||||
const tx: TransactionOptions = {
|
||||
Account: account.address,
|
||||
Sequence: account.sequence,
|
||||
Fee, // TODO auto-fillable default
|
||||
...opts,
|
||||
};
|
||||
const { logPrefix = "" } = options || {};
|
||||
try {
|
||||
const signedAccount = derive.familySeed(account.secret);
|
||||
const { signedTransaction } = sign(tx, signedAccount);
|
||||
const response = await state.client.send({
|
||||
command: "submit",
|
||||
tx_blob: signedTransaction,
|
||||
});
|
||||
|
||||
const resultMsg = ref(
|
||||
<>
|
||||
{logPrefix}[<ResultLink result={response.engine_result} />]{" "}
|
||||
{response.engine_result_message}
|
||||
</>
|
||||
);
|
||||
if (response.engine_result === "tesSUCCESS") {
|
||||
state.transactionLogs.push({
|
||||
type: "success",
|
||||
message: resultMsg,
|
||||
});
|
||||
} else if (response.engine_result) {
|
||||
state.transactionLogs.push({
|
||||
type: "error",
|
||||
message: resultMsg,
|
||||
});
|
||||
} else {
|
||||
state.transactionLogs.push({
|
||||
type: "error",
|
||||
message: `${logPrefix}[${response.error}] ${response.error_exception}`,
|
||||
});
|
||||
}
|
||||
const currAcc = state.accounts.find(acc => acc.address === account.address);
|
||||
if (currAcc && response.account_sequence_next) {
|
||||
currAcc.sequence = response.account_sequence_next;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
state.transactionLogs.push({
|
||||
type: "error",
|
||||
message:
|
||||
err instanceof Error
|
||||
? `${logPrefix}Error: ${err.message}`
|
||||
: `${logPrefix}Something went wrong, try again later`,
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user