Merge branch 'main' into feat/engine-code-links

This commit is contained in:
muzam1l
2022-08-19 15:07:44 +05:30
115 changed files with 6250 additions and 6080 deletions

View File

@@ -1,54 +1,52 @@
import { derive, sign } from "xrpl-accountlib";
import toast from "react-hot-toast";
import { derive, sign } from 'xrpl-accountlib'
import toast from 'react-hot-toast'
import state, { IAccount } from "../index";
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 ResultLink from "../../components/ResultLink";
import state, { IAccount } from '../index'
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 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"))
.join("");
return hashHex;
};
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')).join('')
return hashHex
}
function toHex(str: string) {
var result = "";
var result = ''
for (var i = 0; i < str.length; i++) {
result += str.charCodeAt(i).toString(16);
result += str.charCodeAt(i).toString(16)
}
return result.toUpperCase();
return result.toUpperCase()
}
function arrayBufferToHex(arrayBuffer?: ArrayBuffer | null) {
if (!arrayBuffer) {
return "";
return ''
}
if (
typeof arrayBuffer !== "object" ||
typeof arrayBuffer !== 'object' ||
arrayBuffer === null ||
typeof arrayBuffer.byteLength !== "number"
typeof arrayBuffer.byteLength !== 'number'
) {
throw new TypeError("Expected input to be an ArrayBuffer");
throw new TypeError('Expected input to be an ArrayBuffer')
}
var view = new Uint8Array(arrayBuffer);
var result = "";
var value;
var view = new Uint8Array(arrayBuffer)
var result = ''
var value
for (var i = 0; i < view.length; i++) {
value = view[i].toString(16);
result += value.length === 1 ? "0" + value : value;
value = view[i].toString(16)
result += value.length === 1 ? '0' + value : value
}
return result;
return result
}
export const prepareDeployHookTx = async (
@@ -57,30 +55,29 @@ 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;
return
}
if (!activeFile?.compiledContent) {
return;
return
}
if (!state.client) {
return;
return
}
const HookNamespace = (await sha256(data.HookNamespace)).toUpperCase();
const hookOnValues: (keyof TTS)[] = data.Invoke.map(tt => tt.value);
const { HookParameters } = data;
const HookNamespace = (await sha256(data.HookNamespace)).toUpperCase()
const hookOnValues: (keyof TTS)[] = data.Invoke.map(tt => tt.value)
const { HookParameters } = data
const filteredHookParameters = HookParameters.filter(
hp =>
hp.HookParameter.HookParameterName && hp.HookParameter.HookParameterValue
hp => hp.HookParameter.HookParameterName && hp.HookParameter.HookParameterValue
)?.map(aa => ({
HookParameter: {
HookParameterName: toHex(aa.HookParameter.HookParameterName || ""),
HookParameterValue: aa.HookParameter.HookParameterValue || "",
},
}));
HookParameterName: toHex(aa.HookParameter.HookParameterName || ''),
HookParameterValue: aa.HookParameter.HookParameterValue || ''
}
}))
// const filteredHookGrants = HookGrants.filter(hg => hg.HookGrant.Authorize || hg.HookGrant.HookHash).map(hg => {
// return {
// HookGrant: {
@@ -90,79 +87,71 @@ export const prepareDeployHookTx = async (
// }
// }
// });
if (typeof window !== "undefined") {
if (typeof window !== 'undefined') {
const tx = {
Account: account.address,
TransactionType: "SetHook",
TransactionType: 'SetHook',
Sequence: account.sequence,
Fee: data.Fee,
Hooks: [
{
Hook: {
CreateCode: arrayBufferToHex(
activeFile?.compiledContent
).toUpperCase(),
CreateCode: arrayBufferToHex(activeFile?.compiledContent).toUpperCase(),
HookOn: calculateHookOn(hookOnValues),
HookNamespace,
HookApiVersion: 0,
Flags: 1,
// ...(filteredHookGrants.length > 0 && { HookGrants: filteredHookGrants }),
...(filteredHookParameters.length > 0 && {
HookParameters: filteredHookParameters,
}),
},
},
],
};
return tx;
HookParameters: filteredHookParameters
})
}
}
]
}
return tx
}
};
}
/* deployHook function turns the wasm binary into
* hex string, signs the transaction and deploys it to
* Hooks testnet.
*/
export const deployHook = async (
account: IAccount & { name?: string },
data: SetHookData
) => {
if (typeof window !== "undefined") {
export const deployHook = async (account: IAccount & { name?: string }, data: SetHookData) => {
if (typeof window !== 'undefined') {
const activeFile = state.files[state.active]?.compiledContent
? state.files[state.active]
: state.files.filter(file => file.compiledContent)[0];
state.deployValues[activeFile.name] = data;
const tx = await prepareDeployHookTx(account, data);
: state.files.filter(file => file.compiledContent)[0]
state.deployValues[activeFile.name] = data
const tx = await prepareDeployHookTx(account, data)
if (!tx) {
return;
return
}
if (!state.client) {
return;
return
}
const keypair = derive.familySeed(account.secret);
const keypair = derive.familySeed(account.secret)
const { signedTransaction } = sign(tx, keypair);
const currentAccount = state.accounts.find(
acc => acc.address === account.address
);
const { signedTransaction } = sign(tx, keypair)
const currentAccount = state.accounts.find(acc => acc.address === account.address)
if (currentAccount) {
currentAccount.isLoading = true;
currentAccount.isLoading = true
}
let submitRes;
let submitRes
try {
submitRes = await state.client?.send({
command: "submit",
tx_blob: signedTransaction,
});
command: 'submit',
tx_blob: signedTransaction
})
const txHash = submitRes.tx_json?.hash;
const txHash = submitRes.tx_json?.hash
const resultMsg = ref(
<>
[<ResultLink result={submitRes.engine_result} />]{" "}
{submitRes.engine_result_message}{" "}
[<ResultLink result={submitRes.engine_result} />] {submitRes.engine_result_message}{' '}
{txHash && (
<>
Transaction hash:{" "}
Transaction hash:{' '}
<Link
as="a"
href={`https://${process.env.NEXT_PUBLIC_EXPLORER_URL}/${txHash}`}
@@ -174,123 +163,120 @@ export const deployHook = async (
</>
)}
</>
);
if (submitRes.engine_result === "tesSUCCESS") {
)
if (submitRes.engine_result === 'tesSUCCESS') {
state.deployLogs.push({
type: "success",
message: "Hook deployed successfully ✅",
});
type: 'success',
message: 'Hook deployed successfully ✅'
})
state.deployLogs.push({
type: "success",
message: resultMsg,
});
type: 'success',
message: resultMsg
})
} else if (submitRes.engine_result) {
state.deployLogs.push({
type: "error",
message: resultMsg,
});
type: 'error',
message: resultMsg
})
} else {
state.deployLogs.push({
type: "error",
message: `[${submitRes.error}] ${submitRes.error_exception}`,
});
type: 'error',
message: `[${submitRes.error}] ${submitRes.error_exception}`
})
}
} catch (err) {
console.log(err);
console.log(err)
state.deployLogs.push({
type: "error",
message: "Error occurred while deploying",
});
type: 'error',
message: 'Error occurred while deploying'
})
}
if (currentAccount) {
currentAccount.isLoading = false;
currentAccount.isLoading = false
}
return submitRes;
return submitRes
}
};
}
export const deleteHook = async (account: IAccount & { name?: string }) => {
if (!state.client) {
return;
return
}
const currentAccount = state.accounts.find(
acc => acc.address === account.address
);
const currentAccount = state.accounts.find(acc => acc.address === account.address)
if (currentAccount?.isLoading || !currentAccount?.hooks.length) {
return;
return
}
if (typeof window !== "undefined") {
if (typeof window !== 'undefined') {
const tx = {
Account: account.address,
TransactionType: "SetHook",
TransactionType: 'SetHook',
Sequence: account.sequence,
Fee: "100000",
Fee: '100000',
Hooks: [
{
Hook: {
CreateCode: "",
Flags: 1,
},
},
],
};
CreateCode: '',
Flags: 1
}
}
]
}
const keypair = derive.familySeed(account.secret);
const keypair = derive.familySeed(account.secret)
try {
// Update tx Fee value with network estimation
const res = await estimateFee(tx, account);
tx["Fee"] = res?.base_fee ? res?.base_fee : "1000";
const res = await estimateFee(tx, account)
tx['Fee'] = res?.base_fee ? res?.base_fee : '1000'
} catch (err) {
// use default value what you defined earlier
console.log(err);
console.log(err)
}
const { signedTransaction } = sign(tx, keypair);
const { signedTransaction } = sign(tx, keypair)
if (currentAccount) {
currentAccount.isLoading = true;
currentAccount.isLoading = true
}
let submitRes;
const toastId = toast.loading("Deleting hook...");
let submitRes
const toastId = toast.loading('Deleting hook...')
try {
submitRes = await state.client.send({
command: "submit",
tx_blob: signedTransaction,
});
command: 'submit',
tx_blob: signedTransaction
})
if (submitRes.engine_result === "tesSUCCESS") {
toast.success("Hook deleted successfully ✅", { id: toastId });
if (submitRes.engine_result === 'tesSUCCESS') {
toast.success('Hook deleted successfully ✅', { id: toastId })
state.deployLogs.push({
type: "success",
message: "Hook deleted successfully ✅",
});
type: 'success',
message: 'Hook deleted successfully ✅'
})
state.deployLogs.push({
type: "success",
message: `[${submitRes.engine_result}] ${submitRes.engine_result_message} Validated ledger index: ${submitRes.validated_ledger_index}`,
});
currentAccount.hooks = [];
type: 'success',
message: `[${submitRes.engine_result}] ${submitRes.engine_result_message} Validated ledger index: ${submitRes.validated_ledger_index}`
})
currentAccount.hooks = []
} else {
toast.error(
`${submitRes.engine_result_message || submitRes.error_exception}`,
{ id: toastId }
);
toast.error(`${submitRes.engine_result_message || submitRes.error_exception}`, {
id: toastId
})
state.deployLogs.push({
type: "error",
type: 'error',
message: `[${submitRes.engine_result || submitRes.error}] ${
submitRes.engine_result_message || submitRes.error_exception
}`,
});
}`
})
}
} catch (err) {
console.log(err);
toast.error("Error occurred while deleting hook", { id: toastId });
console.log(err)
toast.error('Error occurred while deleting hook', { id: toastId })
state.deployLogs.push({
type: "error",
message: "Error occurred while deleting hook",
});
type: 'error',
message: 'Error occurred while deleting hook'
})
}
if (currentAccount) {
currentAccount.isLoading = false;
currentAccount.isLoading = false
}
return submitRes;
return submitRes
}
};
}