<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>WASM Example</title>
</head>
<body>
<label for="accountFileInput" class="custom-file-upload">
Choose Account File
</label>
<input type="file" id="accountFileInput" style="display: none" />
<label for="noteFileInput" class="custom-file-upload">
Choose Note File
</label>
<input type="file" id="noteFileInput" style="display: none" />
<script type="module" src="./dist/index.js"></script>
<script type="module">
import {
AdviceMap,
AccountStorageMode,
AuthSecretKey,
Felt,
FeltArray,
FungibleAsset,
InputNoteState,
Note,
NoteAssets,
NoteExecutionHint,
NoteExecutionMode,
NoteFilter,
NoteId,
NoteIdAndArgs,
NoteIdAndArgsArray,
NoteInputs,
NoteMetadata,
NoteRecipient,
NoteTag,
NoteType,
OutputNote,
OutputNotesArray,
Rpo256,
TransactionRequest,
TransactionRequestBuilder,
TransactionScriptInputPair,
TransactionScriptInputPairArray,
WebClient,
} from "./dist/index.js";
document
.getElementById("accountFileInput")
.addEventListener("change", function (event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = async function (e) {
let webClient = await createMidenWebClient();
const arrayBuffer = e.target.result;
const byteArray = new Uint8Array(arrayBuffer);
await testImportAccount(webClient, byteArray);
};
reader.readAsArrayBuffer(file);
}
});
document
.getElementById("noteFileInput")
.addEventListener("change", async function (event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = async function (e) {
let webClient = await createMidenWebClient();
const arrayBuffer = e.target.result;
const byteArray = new Uint8Array(arrayBuffer);
await importInputNote(webClient, byteArray, true);
};
reader.readAsArrayBuffer(file);
}
});
function setupNoteFileInputListener(webClient) {
document
.getElementById("noteFileInput")
.addEventListener("change", async function (event) {
const file = event.target.files[0];
if (file) {
try {
const byteArray = await readFileAsByteArray(file);
console.log(byteArray); let result = await importInputNote(webClient, byteArray);
console.log(result); } catch (error) {
console.error("Error handling file:", error);
}
}
});
}
async function readFileAsByteArray(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => {
const arrayBuffer = reader.result;
const byteArray = new Uint8Array(arrayBuffer);
console.log("Byte array length:", byteArray.length); resolve(byteArray);
};
reader.onerror = () => {
console.error("File read error:", reader.error);
reject(reader.error);
};
reader.readAsArrayBuffer(file);
});
}
async function createMidenWebClient(dbName = "MidenClientDB", initSeed) {
try {
let rpc_url = "http://localhost:57291";
let envoy_proxy_url = "http://localhost:8080";
const webClient = new WebClient();
await webClient.create_client(rpc_url, null, initSeed);
return webClient;
} catch (error) {
console.error("Failed to create client with web store:", error);
}
}
async function testStoreAndRpc(webClient) {
try {
await webClient.test_store_and_rpc();
} catch (error) {
console.error("Failed to create client with web store:", error);
}
}
async function createNewWallet(webClient, storageMode, mutable) {
try {
let result = await webClient.new_wallet(storageMode, mutable);
console.log(`Created new wallet account with id ${result}`);
return result;
} catch (error) {
console.error("Failed to call create account:", error);
}
}
async function createNewFaucet(
webClient,
storageMode,
nonFungible,
tokenSymbol,
decimals,
maxSupply
) {
try {
let result = await webClient.new_faucet(
storageMode,
nonFungible,
tokenSymbol,
decimals,
maxSupply
);
console.log(`Created new faucet with id ${result}`);
return result;
} catch (error) {
console.error("Failed to call create account:", error);
}
}
async function importAccount(webClient, accountAsBytes) {
try {
let result = await webClient.import_account(accountAsBytes);
console.log(result);
return result;
} catch (error) {
console.error("Failed to call import account:", error);
}
}
async function getAccounts(webClient) {
try {
let accounts = await webClient.get_accounts();
let accountIds = accounts.map((account) => account.id);
console.log(accountIds);
return accountIds;
} catch (error) {
console.error("Failed to call get accounts:", error);
}
}
async function getAccount(webClient, accountId) {
try {
let result = await webClient.get_account(accountId);
console.log(result);
return result;
} catch (error) {
console.error("Failed to call get account:", error);
}
}
async function createNewMintTransaction(
webClient,
targetAccountId,
faucetId,
noteType,
amount
) {
try {
let result = await webClient.new_mint_transaction(
targetAccountId,
faucetId,
noteType,
amount
);
console.log(
`Created new mint transaction with id ${result.transaction_id}`
);
console.log(`Output notes created: ${result.created_note_ids}`);
return result;
} catch (error) {
console.error("Failed to call create new mint transaction:", error);
}
}
async function createNewConsumeTransaction(
webClient,
accountId,
listOfNotes
) {
try {
let result = await webClient.new_consume_transaction(
accountId,
listOfNotes
);
console.log(
`Created new consume transaction with id ${result.transaction_id}`
);
console.log(`Output notes created: ${result.created_note_ids}`);
return result;
} catch (error) {
console.error(
"Failed to call create new consume transaction:",
error
);
}
}
async function createNewSendTransaction(
webClient,
senderAccountId,
targetAccountId,
facuetId,
noteType,
amount,
recallHeight
) {
try {
let result = await webClient.new_send_transaction(
senderAccountId,
targetAccountId,
facuetId,
noteType,
amount,
recallHeight
);
console.log(
`Created new send transaction with id ${result.transaction_id}`
);
console.log(`Output notes created: ${result.created_note_ids}`);
return result;
} catch (error) {
console.error("Failed to call create new send transaction:", error);
}
}
async function createNewSwapTransaction(
webClient,
senderAccountId,
offeredAssetFaucetId,
offeredAssetAmount,
requestedAssetFaucetId,
requestedAssetAmount,
noteType
) {
try {
let result = await webClient.new_swap_transaction(
senderAccountId,
offeredAssetFaucetId,
offeredAssetAmount,
requestedAssetFaucetId,
requestedAssetAmount,
noteType
);
console.log(
`Created new swap transaction with id ${result.transaction_id}`
);
console.log(
`Output notes created: ${result.expected_output_note_ids}`
);
console.log(
`Expected Partial Notes: ${result.expected_partial_note_ids}`
);
console.log(`Payback Note Tag: ${result.payback_note_tag}`);
return result;
} catch (error) {
console.error("Failed to call create new swap transaction:", error);
}
}
async function getTransactions(webClient) {
try {
let result = await webClient.get_transactions();
console.log(result);
return result;
} catch (error) {
console.error("Failed to call get transactions:", error);
}
}
async function getInputNotes(webClient, status = "All") {
try {
let result = await webClient.get_input_notes(status);
console.log(result);
return result;
} catch (error) {
console.error("Failed to call get input notes:", error);
}
}
async function getInputNote(webClient, noteId) {
try {
let result = await webClient.get_input_note(noteId);
console.log(result);
return result;
} catch (error) {
console.error("Failed to call get input note:", error);
}
}
async function getOutputNotes(webClient, status = "All") {
try {
let result = await webClient.get_output_notes(status);
console.log(result);
return result;
} catch (error) {
console.error("Failed to call get output notes:", error);
}
}
async function getOutputNote(webClient, noteId) {
try {
let result = await webClient.get_output_note(noteId);
console.log(result);
return result;
} catch (error) {
console.error("Failed to call get input note:", error);
}
}
async function importInputNote(webClient, noteAsBytes, verify) {
try {
await webClient.import_note(noteAsBytes, verify);
} catch (error) {
console.error("Failed to call import input note:", error);
}
}
async function exportNote(webClient, noteId) {
try {
let result = await webClient.export_note(noteId, "Partial");
let byteArray = new Uint8Array(result);
console.log(byteArray);
return byteArray;
} catch (error) {
console.error("Failed to call export input note:", error);
}
}
async function syncState(webClient) {
try {
let result = await webClient.sync_state();
console.log("Synced state to block ", result);
} catch (error) {
console.error("Failed to call sync state:", error);
}
}
async function addTag(webClient, noteTag) {
try {
let result = await webClient.add_tag(noteTag);
console.log(result);
} catch (error) {
console.error("Failed to call add note tag:", error);
}
}
async function testCreateNewWallet() {
const initSeed = new Uint8Array([
223, 198, 73, 130, 93, 79, 220, 107, 25, 181, 91, 235, 101, 105, 136,
172, 151, 161, 174, 73, 142, 81, 238, 192, 227, 93, 54, 113, 136, 223,
75, 174,
]);
console.log("testCreateNewWallet started");
const webClient = await createMidenWebClient("MidenClientDB", initSeed);
const wallet = await webClient.new_wallet(
AccountStorageMode.public(),
true
);
console.log("Wallet id: ");
console.log(wallet.id().to_string());
console.log("testCreateNewWallet finished");
}
async function testCreateNewFaucet() {
console.log("testCreateNewFaucet started");
let webClient = await createMidenWebClient();
await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
console.log("testCreateNewFaucet finished");
}
async function testImportAccount(webClient, accountAsBytes) {
console.log("testImportAccount started");
await importAccount(webClient, accountAsBytes);
console.log("testImportAccount finished");
}
async function testGetAccounts(shouldCreateAccounts = true) {
console.log("testGetAccounts started");
let webClient = await createMidenWebClient();
if (shouldCreateAccounts) {
await createNewWallet(webClient, "Private", true);
}
await getAccounts(webClient);
console.log("testGetAccounts finished");
}
async function testGetAccount() {
console.log("testGetAccount started");
let webClient = await createMidenWebClient();
let accountId = await createNewWallet(webClient, "Private", true);
await getAccount(webClient, accountId.to_string());
console.log("testGetAccount finished");
}
async function testNewMintTransaction() {
console.log("testNewMintTransaction started");
let webClient = await createMidenWebClient();
let targetAccount = await createNewWallet(
webClient,
AccountStorageMode.private(),
true
);
let faucet = await createNewFaucet(
webClient,
AccountStorageMode.private(),
false,
"DAG",
8,
BigInt(10000000)
);
console.log("syncing state...");
await syncState(webClient);
console.log("state synced");
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(faucet.id());
console.log("fetched");
let result = await createNewMintTransaction(
webClient,
targetAccount.id(),
faucet.id(),
NoteType.private(),
BigInt(1000)
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
console.log("testNewMintTransaction finished");
}
async function testNewConsumeTransaction() {
console.log("testNewConsumeTransaction started");
let webClient = await createMidenWebClient();
let targetAccount = await createNewWallet(
webClient,
AccountStorageMode.private(),
true
);
let faucet = await createNewFaucet(
webClient,
AccountStorageMode.private(),
false,
"DEN",
10,
BigInt(1000000)
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(faucet.id());
let mintTransactionResult = await createNewMintTransaction(
webClient,
targetAccount.id(),
faucet.id(),
NoteType.private(),
BigInt(1000)
);
let created_notes = mintTransactionResult.created_notes().notes();
let created_note_ids = created_notes.map((note) =>
note.id().to_string()
);
console.log("waiting on minted notes to get eaten by the rpc...");
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccount.id()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
targetAccount.id(),
created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
console.log("testNewConsumeTransaction finished");
}
async function testNewSendTransaction() {
console.log("testNewSendTransaction started");
let webClient = await createMidenWebClient();
let senderAccountId = await createNewWallet(webClient, "Private", true);
let targetAccountId = await createNewWallet(webClient, "Private", true);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
senderAccountId.to_string(),
faucetId.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
senderAccountId.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
senderAccountId.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
senderAccountId.to_string()
);
let sendTransactionResult = await createNewSendTransaction(
webClient,
senderAccountId.to_string(),
targetAccountId.to_string(),
faucetId.to_string(),
"Private",
"500",
null
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccountId.to_string()
);
let consumeSendTransactionResult = await createNewConsumeTransaction(
webClient,
targetAccountId.to_string(),
sendTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
console.log("testNewSendTransaction finished");
}
async function testNewSendTransactionWithRecallHeight() {
console.log("testNewSendTransactionWithRecallHeight started");
let webClient = await createMidenWebClient();
let senderAccountId = await createNewWallet(webClient, "Private", true);
let targetAccountId = await createNewWallet(webClient, "Private", true);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
senderAccountId.to_string(),
faucetId.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
senderAccountId.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
senderAccountId.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
senderAccountId.to_string()
);
let sendTransactionResult = await createNewSendTransaction(
webClient,
senderAccountId.to_string(),
targetAccountId.to_string(),
faucetId.to_string(),
"Private",
"500",
"0"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
senderAccountId.to_string()
);
let consumeSendTransactionResult = await createNewConsumeTransaction(
webClient,
senderAccountId.to_string(),
sendTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
console.log("testNewSendTransactionWithRecallHeight finished");
}
async function testNewSwapTransaction() {
console.log("testNewSwapTransaction started");
let webClient = await createMidenWebClient();
let walletAAccountId = await createNewWallet(
webClient,
"Private",
true
);
let walletBAccountId = await createNewWallet(
webClient,
"Private",
true
);
let offeredAssetFaucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
let requestedAssetFaucetId = await createNewFaucet(
webClient,
"Private",
false,
"GAR",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
offeredAssetFaucetId.to_string()
);
let walletAMintTransactionResult = await createNewMintTransaction(
webClient,
walletAAccountId.to_string(),
offeredAssetFaucetId.to_string(),
"Public",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
requestedAssetFaucetId.to_string()
);
let walletBMintTransactionResult = await createNewMintTransaction(
webClient,
walletBAccountId.to_string(),
requestedAssetFaucetId.to_string(),
"Public",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletAAccountId.to_string()
);
let walletAConsumeTransactionResult = await createNewConsumeTransaction(
webClient,
walletAAccountId.to_string(),
walletAMintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletBAccountId.to_string()
);
let walletBConsumeTransactionResult = await createNewConsumeTransaction(
webClient,
walletBAccountId.to_string(),
walletBMintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletAAccountId.to_string()
);
let swapTransactionResult = await createNewSwapTransaction(
webClient,
walletAAccountId.to_string(),
offeredAssetFaucetId.to_string(),
"100",
requestedAssetFaucetId.to_string(),
"900",
"Public"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await addTag(webClient, swapTransactionResult.payback_note_tag);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletBAccountId.to_string()
);
let walletBConsumeSwapTransactionResult =
await createNewConsumeTransaction(
webClient,
walletBAccountId.to_string(),
swapTransactionResult.expected_output_note_ids );
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletAAccountId.to_string()
);
let walletAConsumeSwapTransactionResult =
await createNewConsumeTransaction(
webClient,
walletAAccountId.to_string(),
swapTransactionResult.expected_partial_note_ids );
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
console.log("testNewSwapTransaction finished");
}
async function testGetTransactions() {
console.log("testGetTransactions started");
let webClient = await createMidenWebClient();
let walletAccount = await createNewWallet(webClient, "Private", true);
let faucetAccount = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetAccount.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
walletAccount.to_string(),
faucetAccount.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletAccount.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
walletAccount.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await getTransactions(webClient);
console.log("testGetTransactions finished");
}
async function testGetInputNotes() {
console.log("testGetInputNotes started");
let webClient = await createMidenWebClient();
let targetAccountId = await createNewWallet(webClient, "Private", true);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
targetAccountId.to_string(),
faucetId.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccountId.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
targetAccountId.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await getInputNotes(webClient);
console.log("testGetInputNotes finished");
}
async function testGetInputNote() {
console.log("testGetInputNote started");
let webClient = await createMidenWebClient();
let targetAccountId = await createNewWallet(webClient, "Private", true);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
targetAccountId.to_string(),
faucetId.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccountId.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
targetAccountId.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await getInputNote(
webClient,
mintTransactionResult.created_note_ids[0]
);
console.log("testGetInputNote finished");
}
async function testGetNote() {
console.log("testGetNote started");
let webClient = await createMidenWebClient();
let regularAccountTemplate = createBasicMutableAccountTemplate("Local");
let fungibleFaucetAccountTemplate = createFungibleFaucetAccountTemplate(
"DEN",
"10",
"1000000",
"Local"
);
let regularAccountId = await createNewAccount(
webClient,
regularAccountTemplate
);
let faucetId = await createNewAccount(
webClient,
fungibleFaucetAccountTemplate
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 10000));
let transactionTemplate = createMintTransactionTemplate(
regularAccountId,
faucetId,
"1000",
"Private"
);
let createTransactionResult = await createTransaction(
webClient,
transactionTemplate
);
await new Promise((r) => setTimeout(r, 10000));
await syncState(webClient);
await getInputNote(
webClient,
createTransactionResult.created_note_ids[0]
);
console.log("testGetNote finished");
}
async function testGetOutputNotes() {
console.log("testGetOutputNotes started");
let webClient = await createMidenWebClient();
let targetAccountId = await createNewWallet(webClient, "Private", true);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
targetAccountId.to_string(),
faucetId.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccountId.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
targetAccountId.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await getOutputNotes(webClient);
console.log("testGetOutputNotes finished");
}
async function testGetOutputNote() {
console.log("testGetOutputNote started");
let webClient = await createMidenWebClient();
let targetAccountId = await createNewWallet(webClient, "Private", true);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let mintTransactionResult = await createNewMintTransaction(
webClient,
targetAccountId.to_string(),
faucetId.to_string(),
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccountId.to_string()
);
let consumeTransactionResult = await createNewConsumeTransaction(
webClient,
targetAccountId.to_string(),
mintTransactionResult.created_note_ids
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
await getOutputNote(
webClient,
mintTransactionResult.created_note_ids[0]
);
console.log("testGetOutputNote finished");
}
async function testExportNote() {
console.log("testExportNote started");
let webClient = await createMidenWebClient();
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
await new Promise((r) => setTimeout(r, 20000));
await webClient.fetch_and_cache_account_auth_by_pub_key(faucetId);
let mintTransactionResult = await createNewMintTransaction(
webClient,
"0x9186b96f559e852f", faucetId,
"Private",
"1000"
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
let result = await exportNote(
webClient,
mintTransactionResult.created_note_ids[0]
);
const blob = new Blob([result], { type: "application/octet-stream" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "exportNoteTest.mno";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
console.log("testExportNote finished");
}
async function testImportInputNote() {
console.log("testImportInputNote started");
let webClient = await createMidenWebClient();
let walletAccount = await createNewWallet(webClient, "Private", true);
function setupNoteFileInputListener(webClient, targetAccountId) {
document
.getElementById("noteFileInput")
.addEventListener("change", async function (event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = async function (e) {
const arrayBuffer = e.target.result;
const byteArray = new Uint8Array(arrayBuffer);
console.log(byteArray);
let result = await importInputNote(
webClient,
byteArray,
false
);
console.log(result);
await webClient.fetch_and_cache_account_auth_by_pub_key(
targetAccountId
);
let consumeTransactionResult =
await createNewConsumeTransaction(
webClient,
"0x98f63aaa54c58c14",
[result]
);
await new Promise((r) => setTimeout(r, 20000));
await syncState(webClient);
console.log("testImportInputNote finished");
};
reader.readAsArrayBuffer(file);
}
});
}
setupNoteFileInputListener(webClient, walletAccount);
}
async function testCustomTransaction() {
console.log("testCustomTransaction started");
let webClient = await createMidenWebClient();
let walletId = await createNewWallet(webClient, "Private", false);
let faucetId = await createNewFaucet(
webClient,
"Private",
false,
"DEN",
"10",
"1000000"
);
await syncState(webClient);
let felt1 = new Felt(BigInt(9));
let felt2 = new Felt(BigInt(12));
let felt3 = new Felt(BigInt(18));
let felt4 = new Felt(BigInt(3));
let felt5 = new Felt(BigInt(3));
let felt6 = new Felt(BigInt(18));
let felt7 = new Felt(BigInt(12));
let felt8 = new Felt(BigInt(9));
let noteArgs = [felt1, felt2, felt3, felt4, felt5, felt6, felt7, felt8];
let feltArray = new FeltArray();
noteArgs.forEach((felt) => feltArray.append(felt));
let noteAssets = new NoteAssets([
new FungibleAsset(faucetId, BigInt(10)),
]);
let noteMetadata = new NoteMetadata(
faucetId,
NoteType.private(),
NoteTag.from_account_id(walletId, NoteExecutionMode.new_local()),
NoteExecutionHint.none(),
null
);
let expectedNoteArgs = noteArgs.map((felt) => felt.as_int());
let memAddress = "1000";
let memAddress2 = "1004";
let expectedNoteArg1 = expectedNoteArgs.slice(0, 4).join(".");
let expectedNoteArg2 = expectedNoteArgs.slice(4, 8).join(".");
let note_script = `
# Custom P2ID note script
#
# This note script asserts that the note args are exactly the same as passed
# (currently defined as {expected_note_arg_1} and {expected_note_arg_2}).
# Since the args are too big to fit in a single note arg, we provide them via advice inputs and
# address them via their commitment (noted as NOTE_ARG)
# This note script is based off of the P2ID note script because notes currently need to have
# assets, otherwise it could have been boiled down to the assert.
use.miden::account
use.miden::note
use.miden::contracts::wallets::basic->wallet
use.std::mem
proc.add_note_assets_to_account
push.0 exec.note::get_assets
# => [num_of_assets, 0 = ptr, ...]
# compute the pointer at which we should stop iterating
mul.4 dup.1 add
# => [end_ptr, ptr, ...]
# pad the stack and move the pointer to the top
padw movup.5
# => [ptr, 0, 0, 0, 0, end_ptr, ...]
# compute the loop latch
dup dup.6 neq
# => [latch, ptr, 0, 0, 0, 0, end_ptr, ...]
while.true
# => [ptr, 0, 0, 0, 0, end_ptr, ...]
# save the pointer so that we can use it later
dup movdn.5
# => [ptr, 0, 0, 0, 0, ptr, end_ptr, ...]
# load the asset
mem_loadw
# => [ASSET, ptr, end_ptr, ...]
# pad the stack before call
padw swapw padw padw swapdw
# => [ASSET, pad(12), ptr, end_ptr, ...]
# add asset to the account
call.wallet::receive_asset
# => [pad(16), ptr, end_ptr, ...]
# clean the stack after call
dropw dropw dropw
# => [0, 0, 0, 0, ptr, end_ptr, ...]
# increment the pointer and compare it to the end_ptr
movup.4 add.4 dup dup.6 neq
# => [latch, ptr+4, ASSET, end_ptr, ...]
end
# clear the stack
drop dropw drop
end
begin
# push data from the advice map into the advice stack
adv.push_mapval
# => [NOTE_ARG]
# memory address where to write the data
push.${memAddress}
# => [target_mem_addr, NOTE_ARG_COMMITMENT]
# number of words
push.2
# => [number_of_words, target_mem_addr, NOTE_ARG_COMMITMENT]
exec.mem::pipe_preimage_to_memory
# => [target_mem_addr']
dropw
# => []
# read first word
push.${memAddress}
# => [data_mem_address]
mem_loadw
# => [NOTE_ARG_1]
push.${expectedNoteArg1} assert_eqw.err=101
# => []
# read second word
push.${memAddress2}
# => [data_mem_address_2]
mem_loadw
# => [NOTE_ARG_2]
push.${expectedNoteArg2} assert_eqw.err=102
# => []
# store the note inputs to memory starting at address 0
push.0 exec.note::get_inputs
# => [num_inputs, inputs_ptr]
# make sure the number of inputs is 1
eq.2 assert.err=103
# => [inputs_ptr]
# read the target account id from the note inputs
mem_load
# => [target_account_id_prefix]
exec.account::get_id swap drop
# => [account_id_prefix, target_account_id_prefix, ...]
# ensure account_id = target_account_id, fails otherwise
assert_eq.err=104
# => [...]
exec.add_note_assets_to_account
# => [...]
end
`;
let compiledNoteScript =
await webClient.compile_note_script(note_script);
let noteInputs = new NoteInputs(new FeltArray([walletId.to_felt()]));
let noteRecipient = new NoteRecipient(compiledNoteScript, noteInputs);
let note = new Note(noteAssets, noteMetadata, noteRecipient);
let transaction_request = new TransactionRequestBuilder()
.with_own_output_notes(new OutputNotesArray([OutputNote.full(note)]))
.build();
await webClient.fetch_and_cache_account_auth_by_pub_key(
faucetId.to_string()
);
let transaction_result = await webClient.new_transaction(
faucetId,
transaction_request
);
await webClient.submit_transaction(transaction_result);
await new Promise((r) => setTimeout(r, 10000));
await webClient.sync_state();
let tx_script = `
use.miden::contracts::auth::basic->auth_tx
use.miden::kernels::tx::prologue
use.miden::kernels::tx::memory
begin
push.0 push.0
# => [0, 0]
assert_eq
call.auth_tx::auth_tx_rpo_falcon512
end
`;
let account_auth = await webClient.get_account_auth(walletId);
let public_key = account_auth.get_rpo_falcon_512_public_key_as_word();
let secret_key = account_auth.get_rpo_falcon_512_secret_key_as_felts();
let transcription_script_input_pair_array =
new TransactionScriptInputPairArray([
new TransactionScriptInputPair(public_key, secret_key),
]);
let transaction_script = await webClient.compile_tx_script(
tx_script,
transcription_script_input_pair_array
);
let note_id = note.id();
let note_args_commitment = Rpo256.hash_elements(feltArray); let note_id_and_args = new NoteIdAndArgs(
note_id,
note_args_commitment.to_word()
);
let note_id_and_args_array = new NoteIdAndArgsArray([note_id_and_args]);
let advice_map = new AdviceMap();
let note_args_commitment_2 = Rpo256.hash_elements(feltArray);
advice_map.insert(note_args_commitment_2, feltArray);
let transaction_request_2 = new TransactionRequest()
.with_authenticated_input_notes(note_id_and_args_array)
.with_custom_script(transaction_script)
.extend_advice_map(advice_map);
await webClient.fetch_and_cache_account_auth_by_pub_key(
walletId.to_string()
);
let transaction_result_2 = await webClient.new_transaction(
walletId,
transaction_request_2
);
await webClient.submit_transaction(transaction_result_2);
await new Promise((r) => setTimeout(r, 10000));
await webClient.sync_state();
console.log("testCustomTransaction finished");
}
await testCreateNewWallet();
</script>
</body>
</html>