From 37b19d61c023b6930ba9b937a3ea8ad86d2e0e0e Mon Sep 17 00:00:00 2001 From: i Date: Wed, 22 May 2024 12:00:22 +0200 Subject: [PATCH] run dprint on rosetta typescript samples --- .../rosetta/samples/index.mdx | 21 +- .../rosetta/samples/requests.mdx | 220 ++++++---- .../rosetta/samples/scan-blocks.mdx | 20 +- .../rosetta/samples/send-transactions.mdx | 62 +-- .../rosetta/samples/track-deposits.mdx | 44 +- examples/exchange-operators/nodejs/index.ts | 378 ++++++++++-------- 6 files changed, 424 insertions(+), 321 deletions(-) diff --git a/docs/exchange-operators/rosetta/samples/index.mdx b/docs/exchange-operators/rosetta/samples/index.mdx index 01f8c1b08..abdb11cb5 100644 --- a/docs/exchange-operators/rosetta/samples/index.mdx +++ b/docs/exchange-operators/rosetta/samples/index.mdx @@ -16,25 +16,26 @@ Start with the required imports and define constants: ```ts -import { Client } from 'mina-signer' -import axios from 'axios' +import axios from "axios" +import { Client } from "mina-signer" const TESTNET_NETWORK_IDENTIFIER = { - "network_identifier": { - "blockchain": "mina", - "network": "testnet" - } + network_identifier: { + blockchain: "mina", + network: "testnet", + }, } -const MINA_TOKEN_ID = "1" +const MINA_TOKEN_ID = "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf" const MINA_DECIMALS = 9 const MINA_SYMBOL = "MINA" const MINA_CURVE_TYPE = "pallas" -const mina = new Client({network: 'testnet'}) +const mina = new Client({ network: "testnet" }) + const request = axios.create({ - baseURL: "https://rosetta-devnet.minaprotocol.network/" + baseURL: "https://rosetta-devnet.minaprotocol.network/", }) -const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); +const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)) ``` diff --git a/docs/exchange-operators/rosetta/samples/requests.mdx b/docs/exchange-operators/rosetta/samples/requests.mdx index f95771da1..ea89886ca 100644 --- a/docs/exchange-operators/rosetta/samples/requests.mdx +++ b/docs/exchange-operators/rosetta/samples/requests.mdx @@ -24,10 +24,12 @@ First, implement the generic `request` function to perform Rosetta API calls inj ```ts async function makeRequest(endpoint: string, data?: any) { - if (data === undefined) + if (data === undefined) { data = {} - if (endpoint !== '/network/list') - data = {...TESTNET_NETWORK_IDENTIFIER, ...data} + } + if (endpoint !== "/network/list") { + data = { ...TESTNET_NETWORK_IDENTIFIER, ...data } + } const r = await request.post(endpoint, data) return r.data @@ -71,27 +73,27 @@ To implement helpers to construct the objects: ```ts function makeBlockIdentifier(idOrHash: number | string) { - const identifierKey = (typeof idOrHash === "number") ? "index" : "hash" - return { - block_identifier: {[identifierKey]: idOrHash} - } + const identifierKey = (typeof idOrHash === "number") ? "index" : "hash" + return { + block_identifier: { [identifierKey]: idOrHash }, + } } function makeTxIdentifier(hash: string) { - return {"transaction_identifier": {'hash': hash}} + return { transaction_identifier: { hash: hash } } } function makeAccountIdentifier(address: string) { - return { - account_identifier: {address, token_id: MINA_TOKEN_ID} - } + return { + account_identifier: { address, token_id: MINA_TOKEN_ID }, + } } function makePublicKey(publicKey: string) { - return { - hex_bytes: publicKey, - curve_type: MINA_CURVE_TYPE - } + return { + hex_bytes: publicKey, + curve_type: MINA_CURVE_TYPE, + } } ``` @@ -263,44 +265,68 @@ To implement a helper function to construct the operations array for a MINA toke ```ts function makeTransferPayload(from: string, to: string, feeNano: number, valueNano: number) { - - function makeOperation(idx: number, relatedIdxs: number[], op_type: string, addr: string, value: number, isPositive: boolean) { - const relatedOps = (relatedIdxs.length == 0) ? {} : { - related_operations: relatedIdxs.map((i) => { - return {index: i} - }) - } - - return { - operation_identifier: {index: idx}, - ...relatedOps, - type: op_type, - account: { - address: addr, - metadata: { - token_id: MINA_TOKEN_ID - } - }, - amount: { - value: (isPositive ? "" : "-") + value.toString(), - currency: { - symbol: MINA_SYMBOL, - decimals: MINA_DECIMALS - } - } - } + function makeOperation( + idx: number, + relatedIdxs: number[], + opType: string, + addr: string, + value: number, + isPositive: boolean, + ) { + const relatedOps = (relatedIdxs.length == 0) ? {} : { + related_operations: relatedIdxs.map((i) => { + return { index: i } + }), } return { - operations: [ - makeOperation( - 0, [], "fee_payment", from, feeNano, false), - makeOperation( - 1, [], "payment_source_dec", from, valueNano, false), - makeOperation( - 2, [1], "payment_receiver_inc", to, valueNano, true) - ] + operation_identifier: { index: idx }, + ...relatedOps, + type: opType, + account: { + address: addr, + metadata: { + token_id: MINA_TOKEN_ID, + }, + }, + amount: { + value: (isPositive ? "" : "-") + value.toString(), + currency: { + symbol: MINA_SYMBOL, + decimals: MINA_DECIMALS, + }, + }, } + } + + return { + operations: [ + makeOperation( + 0, + [], + "fee_payment", + from, + feeNano, + false, + ), + makeOperation( + 1, + [], + "payment_source_dec", + from, + valueNano, + false, + ), + makeOperation( + 2, + [1], + "payment_receiver_inc", + to, + valueNano, + true, + ), + ], + } } ``` @@ -364,90 +390,110 @@ Now that you have all helpers in place, you can implement all of the Rosetta cli ```ts async function networkList() { - return await makeRequest('/network/list') + return await makeRequest("/network/list") } async function networkStatus() { - return await makeRequest('/network/status') + return await makeRequest("/network/status") } async function networkOptions() { - return await makeRequest('/network/options') + return await makeRequest("/network/options") } async function block(idOrHash: number | string) { - return await makeRequest('/block', makeBlockIdentifier(idOrHash)) + return await makeRequest("/block", makeBlockIdentifier(idOrHash)) } async function mempool() { - return await makeRequest('/mempool') + return await makeRequest("/mempool") } async function mempoolTx(hash: string) { - return await makeRequest('/mempool/transaction', makeTxIdentifier(hash)) + return await makeRequest("/mempool/transaction", makeTxIdentifier(hash)) } async function accountBalance(address: string) { - return await makeRequest('/account/balance', makeAccountIdentifier(address)) + return await makeRequest("/account/balance", makeAccountIdentifier(address)) } async function accountTransactions(address: string) { - return await makeRequest('/search/transactions', {address: address}) + return await makeRequest("/search/transactions", { address: address }) } async function getTransaction(hash: string) { - return await makeRequest('/search/transactions', makeTxIdentifier(hash)) + return await makeRequest("/search/transactions", makeTxIdentifier(hash)) } async function deriveAccountIdentifier(publicKey: string) { - return await makeRequest('/construction/derive', { - public_key: makePublicKey(publicKey) - }) + return await makeRequest("/construction/derive", { + public_key: makePublicKey(publicKey), + }) } async function txPreprocess(from: string, to: string, feeNano: number, valueNano: number) { - const payload = makeTransferPayload(from, to, feeNano, valueNano) - return await makeRequest('/construction/preprocess', payload) + const payload = makeTransferPayload(from, to, feeNano, valueNano) + return await makeRequest("/construction/preprocess", payload) } -async function txMetadata(srcPublicKey: string, srcAddress: string, destAddress: string, feeNano: number, valueNano: number) { - const options = await txPreprocess(srcAddress, destAddress, feeNano, valueNano) - return await makeRequest('/construction/metadata', { - ...options, public_keys: [makePublicKey(srcPublicKey)] - }) +async function txMetadata( + srcPublicKey: string, + srcAddress: string, + destAddress: string, + feeNano: number, + valueNano: number, +) { + const options = await txPreprocess(srcAddress, destAddress, feeNano, valueNano) + return await makeRequest("/construction/metadata", { + ...options, + public_keys: [makePublicKey(srcPublicKey)], + }) } -async function txPayloads(srcPublicKey: string, srcAddress: string, destAddress: string, feeNano: number, valueNano: number) { - // If fee_nano is undefined, it will get suggested fee from /construction/metadata response - const meta = await txMetadata( - srcPublicKey, srcAddress, destAddress, feeNano, valueNano) - - if (feeNano === 0) - feeNano = meta.suggested_fee[0].value - console.log(feeNano) - const operations = makeTransferPayload(srcAddress, destAddress, feeNano, valueNano) - return makeRequest('/construction/payloads', {...operations, ...meta}) +async function txPayloads( + srcPublicKey: string, + srcAddress: string, + destAddress: string, + feeNano: number, + valueNano: number, +) { + // If fee_nano is undefined, it will get suggested fee from /construction/metadata response + const meta = await txMetadata( + srcPublicKey, + srcAddress, + destAddress, + feeNano, + valueNano, + ) + + if (feeNano === 0) { + feeNano = meta.suggested_fee[0].value + } + console.log(feeNano) + const operations = makeTransferPayload(srcAddress, destAddress, feeNano, valueNano) + return makeRequest("/construction/payloads", { ...operations, ...meta }) } async function txCombine(payloadsResponse: any, privateKey: string) { - const combinePayload = mina.rosettaCombinePayload(payloadsResponse, privateKey) - const r = await makeRequest('/construction/combine', combinePayload) - return r + // console.dir(payloadsResponse, {depth: null}) + const combinePayload = mina.rosettaCombinePayload(payloadsResponse, privateKey) + const r = await makeRequest("/construction/combine", combinePayload) + return r } async function txParse(isSigned: boolean, blob: string) { - return makeRequest('/construction/parse', { - signed: isSigned, - transaction: blob - }) + return makeRequest("/construction/parse", { + signed: isSigned, + transaction: blob, + }) } async function txHash(blob: string) { - return await makeRequest('construction/hash', {signed_transaction: blob}) + return await makeRequest("construction/hash", { signed_transaction: blob }) } async function txSubmit(blob: string) { - return await makeRequest('construction/submit', {signed_transaction: blob}) + return await makeRequest("construction/submit", { signed_transaction: blob }) } ``` diff --git a/docs/exchange-operators/rosetta/samples/scan-blocks.mdx b/docs/exchange-operators/rosetta/samples/scan-blocks.mdx index 379638aa2..210902935 100644 --- a/docs/exchange-operators/rosetta/samples/scan-blocks.mdx +++ b/docs/exchange-operators/rosetta/samples/scan-blocks.mdx @@ -13,13 +13,14 @@ To implement a simple function to wait for a given block: ```ts async function waitForBlock(blockHeight: number) { - let latestBlock = (await networkStatus()).current_block_identifier.index - while (true) { - if (blockHeight <= latestBlock) - return await block(blockHeight) - await sleep(10000) - latestBlock = (await networkStatus()).current_block_identifier.index + let latestBlock = (await networkStatus()).current_block_identifier.index + while (true) { + if (blockHeight <= latestBlock) { + return await block(blockHeight) } + await sleep(10000) + latestBlock = (await networkStatus()).current_block_identifier.index + } } ``` @@ -54,11 +55,10 @@ It can be used to scan blocks like this: ```ts let latestBlockHeight = (await network_status()).current_block_identifier.index while (true) { - const lastBlock = waitForBlock(latestBlockHeight) + const lastBlock = waitForBlock(latestBlockHeight) + // some processing according to business logic - # some processing according to business logic - - latestBlockHeight += 1 + latestBlockHeight += 1 } ``` diff --git a/docs/exchange-operators/rosetta/samples/send-transactions.mdx b/docs/exchange-operators/rosetta/samples/send-transactions.mdx index 2dadf23e8..2ddda5448 100644 --- a/docs/exchange-operators/rosetta/samples/send-transactions.mdx +++ b/docs/exchange-operators/rosetta/samples/send-transactions.mdx @@ -34,35 +34,41 @@ The implementation is as follows: ```ts async function send(privateKey: string, to: string, valueNano: number, feeNano: number) { - const publicKey = mina.derivePublicKey(privateKey) - const publicKeyRaw = mina.publicKeyToRaw(publicKey) - // get transfer payload to sign - const payloadsResponse = await txPayloads( - publicKeyRaw, publicKey, to, feeNano, valueNano) - - // sign and combine transfer payload - const combineResponse = await txCombine(payloadsResponse, privateKey) - const blob = combineResponse.signed_transaction - - // // get future transaction hash - const txHashResponse = await txHash(blob) - const hash = txHashResponse.transaction_identifier.hash - - // submit transaction. this call will fail if tx is not in mempool - await txSubmit(blob) - // wait for transaction confirmation: - // for that, track blocks until we meet our transaction in the last one - let latestBlock = (await networkStatus()).current_block_identifier.index - while (true) { - // check if our transaction exists in the latest block - const txs = (await waitForBlock(latestBlock)).block.transactions - const hashes = txs.map((tx: any) => tx.transaction_identifier.hash) - if (hashes.includes(hash)) - break - - latestBlock += 1 + const publicKey = mina.derivePublicKey(privateKey) + const publicKeyRaw = mina.publicKeyToRaw(publicKey) + // get transfer payload to sign + const payloadsResponse = await txPayloads( + publicKeyRaw, + publicKey, + to, + feeNano, + valueNano, + ) + + // sign and combine transfer payload + const combineResponse = await txCombine(payloadsResponse, privateKey) + const blob = combineResponse.signed_transaction + + // // get future transaction hash + const txHashResponse = await txHash(blob) + const hash = txHashResponse.transaction_identifier.hash + + // submit transaction. this call will fail if tx is not in mempool + await txSubmit(blob) + // wait for transaction confirmation: + // for that, track blocks until we meet our transaction in the last one + let latestBlock = (await networkStatus()).current_block_identifier.index + while (true) { + // check if our transaction exists in the latest block + const txs = (await waitForBlock(latestBlock)).block.transactions + const hashes = txs.map((tx: any) => tx.transaction_identifier.hash) + if (hashes.includes(hash)) { + break } - return hash + + latestBlock += 1 + } + return hash } ``` diff --git a/docs/exchange-operators/rosetta/samples/track-deposits.mdx b/docs/exchange-operators/rosetta/samples/track-deposits.mdx index 523ffbdeb..ca5e70849 100644 --- a/docs/exchange-operators/rosetta/samples/track-deposits.mdx +++ b/docs/exchange-operators/rosetta/samples/track-deposits.mdx @@ -15,29 +15,33 @@ For that, iterate through all transactions in each block to search for `payment_ ```ts async function trackDeposit(address: string) { - // some logic we want to execute on deposit - function onDeposit(deposit: any) { - console.log(deposit) + // some logic we want to execute on deposit + function onDeposit(deposit: any) { + console.log(deposit) + } + let latestBlock = (await networkStatus()).current_block_identifier.index + while (true) { + // check if transactions to the deposit address are present in the latest block + const txs = (await waitForBlock(latestBlock)).block.transactions + const deposits = [] + for (let tx of txs) { + for (let op of tx.operations) { + if (op.account.address === address && op.type === "payment_receiver_inc") { + deposits.push({ + tx_hash: tx.transaction_identifier.hash, + amount: op.amount.value, + }) + } + } } - let latestBlock = (await networkStatus()).current_block_identifier.index - while (true) { - // check if transactions to the deposit address are present in the latest block - const txs = (await waitForBlock(latestBlock)).block.transactions - const deposits = [] - for (let tx of txs) - for (let op of tx.operations) - if (op.account.address === address && op.type === 'payment_receiver_inc') - deposits.push({ - tx_hash: tx.transaction_identifier.hash, - amount: op.amount.value - }) - - // process deposits - for (let d of deposits) - onDeposit(d) - latestBlock += 1 + // process deposits + for (let d of deposits) { + onDeposit(d) } + + latestBlock += 1 + } } ``` diff --git a/examples/exchange-operators/nodejs/index.ts b/examples/exchange-operators/nodejs/index.ts index 301fe13f2..9eddc3a2a 100644 --- a/examples/exchange-operators/nodejs/index.ts +++ b/examples/exchange-operators/nodejs/index.ts @@ -1,261 +1,307 @@ -import { Client } from 'mina-signer' -import axios from 'axios' +import axios from "axios" +import { Client } from "mina-signer" const TESTNET_NETWORK_IDENTIFIER = { - "network_identifier": { - "blockchain": "mina", - "network": "testnet" - } + network_identifier: { + blockchain: "mina", + network: "testnet", + }, } const MINA_TOKEN_ID = "wSHV2S4qX9jFsLjQo8r1BsMLH2ZRKsZx6EJd1sbozGPieEC4Jf" const MINA_DECIMALS = 9 const MINA_SYMBOL = "MINA" const MINA_CURVE_TYPE = "pallas" -const mina = new Client({network: 'testnet'}) +const mina = new Client({ network: "testnet" }) const request = axios.create({ - // baseURL: "https://rosetta-devnet.minaprotocol.network/" - baseURL: "https://metric-contractor-inherited-meeting.trycloudflare.com/" + baseURL: "https://rosetta-devnet.minaprotocol.network/", }) -const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); +const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)) async function makeRequest(endpoint: string, data?: any) { - if (data === undefined) - data = {} - if (endpoint !== '/network/list') - data = {...TESTNET_NETWORK_IDENTIFIER, ...data} - - const r = await request.post(endpoint, data) - return r.data + if (data === undefined) { + data = {} + } + if (endpoint !== "/network/list") { + data = { ...TESTNET_NETWORK_IDENTIFIER, ...data } + } + + const r = await request.post(endpoint, data) + return r.data } function makeBlockIdentifier(idOrHash: number | string) { - const identifierKey = (typeof idOrHash === "number") ? "index" : "hash" - return { - block_identifier: {[identifierKey]: idOrHash} - } + const identifierKey = (typeof idOrHash === "number") ? "index" : "hash" + return { + block_identifier: { [identifierKey]: idOrHash }, + } } function makeTxIdentifier(hash: string) { - return {"transaction_identifier": {'hash': hash}} + return { transaction_identifier: { hash: hash } } } function makeAccountIdentifier(address: string) { - return { - account_identifier: {address, token_id: MINA_TOKEN_ID} - } + return { + account_identifier: { address, token_id: MINA_TOKEN_ID }, + } } function makePublicKey(publicKey: string) { - return { - hex_bytes: publicKey, - curve_type: MINA_CURVE_TYPE - } + return { + hex_bytes: publicKey, + curve_type: MINA_CURVE_TYPE, + } } function makeTransferPayload(from: string, to: string, feeNano: number, valueNano: number) { - - function makeOperation(idx: number, relatedIdxs: number[], op_type: string, addr: string, value: number, isPositive: boolean) { - const relatedOps = (relatedIdxs.length == 0) ? {} : { - related_operations: relatedIdxs.map((i) => { - return {index: i} - }) - } - - return { - operation_identifier: {index: idx}, - ...relatedOps, - type: op_type, - account: { - address: addr, - metadata: { - token_id: MINA_TOKEN_ID - } - }, - amount: { - value: (isPositive ? "" : "-") + value.toString(), - currency: { - symbol: MINA_SYMBOL, - decimals: MINA_DECIMALS - } - } - } + function makeOperation( + idx: number, + relatedIdxs: number[], + opType: string, + addr: string, + value: number, + isPositive: boolean, + ) { + const relatedOps = (relatedIdxs.length == 0) ? {} : { + related_operations: relatedIdxs.map((i) => { + return { index: i } + }), } return { - operations: [ - makeOperation( - 0, [], "fee_payment", from, feeNano, false), - makeOperation( - 1, [], "payment_source_dec", from, valueNano, false), - makeOperation( - 2, [1], "payment_receiver_inc", to, valueNano, true) - ] + operation_identifier: { index: idx }, + ...relatedOps, + type: opType, + account: { + address: addr, + metadata: { + token_id: MINA_TOKEN_ID, + }, + }, + amount: { + value: (isPositive ? "" : "-") + value.toString(), + currency: { + symbol: MINA_SYMBOL, + decimals: MINA_DECIMALS, + }, + }, } + } + + return { + operations: [ + makeOperation( + 0, + [], + "fee_payment", + from, + feeNano, + false, + ), + makeOperation( + 1, + [], + "payment_source_dec", + from, + valueNano, + false, + ), + makeOperation( + 2, + [1], + "payment_receiver_inc", + to, + valueNano, + true, + ), + ], + } } async function networkList() { - return await makeRequest('/network/list') + return await makeRequest("/network/list") } async function networkStatus() { - return await makeRequest('/network/status') + return await makeRequest("/network/status") } async function networkOptions() { - return await makeRequest('/network/options') + return await makeRequest("/network/options") } async function block(idOrHash: number | string) { - return await makeRequest('/block', makeBlockIdentifier(idOrHash)) + return await makeRequest("/block", makeBlockIdentifier(idOrHash)) } async function mempool() { - return await makeRequest('/mempool') + return await makeRequest("/mempool") } async function mempoolTx(hash: string) { - return await makeRequest('/mempool/transaction', makeTxIdentifier(hash)) + return await makeRequest("/mempool/transaction", makeTxIdentifier(hash)) } async function accountBalance(address: string) { - return await makeRequest('/account/balance', makeAccountIdentifier(address)) + return await makeRequest("/account/balance", makeAccountIdentifier(address)) } async function accountTransactions(address: string) { - return await makeRequest('/search/transactions', {address: address}) + return await makeRequest("/search/transactions", { address: address }) } async function getTransaction(hash: string) { - return await makeRequest('/search/transactions', makeTxIdentifier(hash)) + return await makeRequest("/search/transactions", makeTxIdentifier(hash)) } async function deriveAccountIdentifier(publicKey: string) { - return await makeRequest('/construction/derive', { - public_key: makePublicKey(publicKey) - }) + return await makeRequest("/construction/derive", { + public_key: makePublicKey(publicKey), + }) } async function txPreprocess(from: string, to: string, feeNano: number, valueNano: number) { - const payload = makeTransferPayload(from, to, feeNano, valueNano) - return await makeRequest('/construction/preprocess', payload) + const payload = makeTransferPayload(from, to, feeNano, valueNano) + return await makeRequest("/construction/preprocess", payload) } -async function txMetadata(srcPublicKey: string, srcAddress: string, destAddress: string, feeNano: number, valueNano: number) { - const options = await txPreprocess(srcAddress, destAddress, feeNano, valueNano) - return await makeRequest('/construction/metadata', { - ...options, public_keys: [makePublicKey(srcPublicKey)] - }) +async function txMetadata( + srcPublicKey: string, + srcAddress: string, + destAddress: string, + feeNano: number, + valueNano: number, +) { + const options = await txPreprocess(srcAddress, destAddress, feeNano, valueNano) + return await makeRequest("/construction/metadata", { + ...options, + public_keys: [makePublicKey(srcPublicKey)], + }) } -async function txPayloads(srcPublicKey: string, srcAddress: string, destAddress: string, feeNano: number, valueNano: number) { - // If fee_nano is undefined, it will get suggested fee from /construction/metadata response - const meta = await txMetadata( - srcPublicKey, srcAddress, destAddress, feeNano, valueNano) - - if (feeNano === 0) - feeNano = meta.suggested_fee[0].value - console.log(feeNano) - const operations = makeTransferPayload(srcAddress, destAddress, feeNano, valueNano) - return makeRequest('/construction/payloads', {...operations, ...meta}) +async function txPayloads( + srcPublicKey: string, + srcAddress: string, + destAddress: string, + feeNano: number, + valueNano: number, +) { + // If fee_nano is undefined, it will get suggested fee from /construction/metadata response + const meta = await txMetadata( + srcPublicKey, + srcAddress, + destAddress, + feeNano, + valueNano, + ) + + if (feeNano === 0) { + feeNano = meta.suggested_fee[0].value + } + console.log(feeNano) + const operations = makeTransferPayload(srcAddress, destAddress, feeNano, valueNano) + return makeRequest("/construction/payloads", { ...operations, ...meta }) } async function txCombine(payloadsResponse: any, privateKey: string) { - // console.dir(payloadsResponse, {depth: null}) - const combinePayload = mina.rosettaCombinePayload(payloadsResponse, privateKey) - const r = await makeRequest('/construction/combine', combinePayload) - return r + // console.dir(payloadsResponse, {depth: null}) + const combinePayload = mina.rosettaCombinePayload(payloadsResponse, privateKey) + const r = await makeRequest("/construction/combine", combinePayload) + return r } async function txParse(isSigned: boolean, blob: string) { - return makeRequest('/construction/parse', { - signed: isSigned, - transaction: blob - }) + return makeRequest("/construction/parse", { + signed: isSigned, + transaction: blob, + }) } async function txHash(blob: string) { - return await makeRequest('construction/hash', {signed_transaction: blob}) + return await makeRequest("construction/hash", { signed_transaction: blob }) } async function txSubmit(blob: string) { - return await makeRequest('construction/submit', {signed_transaction: blob}) + return await makeRequest("construction/submit", { signed_transaction: blob }) } async function waitForBlock(blockHeight: number) { - let latestBlock = (await networkStatus()).current_block_identifier.index - while (true) { - if (blockHeight <= latestBlock) - return await block(blockHeight) - await sleep(10000) - latestBlock = (await networkStatus()).current_block_identifier.index + let latestBlock = (await networkStatus()).current_block_identifier.index + while (true) { + if (blockHeight <= latestBlock) { + return await block(blockHeight) } + await sleep(10000) + latestBlock = (await networkStatus()).current_block_identifier.index + } } async function trackDeposit(address: string) { - // some logic we want to execute on deposit - function onDeposit(deposit: any) { - console.log(deposit) + // some logic we want to execute on deposit + function onDeposit(deposit: any) { + console.log(deposit) + } + let latestBlock = (await networkStatus()).current_block_identifier.index + while (true) { + // check if transactions to the deposit address are present in the latest block + const txs = (await waitForBlock(latestBlock)).block.transactions + const deposits = [] + for (let tx of txs) { + for (let op of tx.operations) { + if (op.account.address === address && op.type === "payment_receiver_inc") { + deposits.push({ + tx_hash: tx.transaction_identifier.hash, + amount: op.amount.value, + }) + } + } } - let latestBlock = (await networkStatus()).current_block_identifier.index - while (true) { - // check if transactions to the deposit address are present in the latest block - const txs = (await waitForBlock(latestBlock)).block.transactions - const deposits = [] - for (let tx of txs) - for (let op of tx.operations) - if (op.account.address === address && op.type === 'payment_receiver_inc') - deposits.push({ - tx_hash: tx.transaction_identifier.hash, - amount: op.amount.value - }) - - // process deposits - for (let d of deposits) - onDeposit(d) - - latestBlock += 1 + + // process deposits + for (let d of deposits) { + onDeposit(d) } -} + latestBlock += 1 + } +} async function send(privateKey: string, to: string, valueNano: number, feeNano: number) { - const publicKey = mina.derivePublicKey(privateKey) - const publicKeyRaw = mina.publicKeyToRaw(publicKey) - // get transfer payload to sign - const payloadsResponse = await txPayloads( - publicKeyRaw, publicKey, to, feeNano, valueNano) - - // sign and combine transfer payload - const combineResponse = await txCombine(payloadsResponse, privateKey) - const blob = combineResponse.signed_transaction - - // // get future transaction hash - const txHashResponse = await txHash(blob) - const hash = txHashResponse.transaction_identifier.hash - - // submit transaction. this call will fail if tx is not in mempool - await txSubmit(blob) - // wait for transaction confirmation: - // for that, track blocks until we meet our transaction in the last one - let latestBlock = (await networkStatus()).current_block_identifier.index - while (true) { - // check if our transaction exists in the latest block - const txs = (await waitForBlock(latestBlock)).block.transactions - const hashes = txs.map((tx: any) => tx.transaction_identifier.hash) - if (hashes.includes(hash)) - break - - latestBlock += 1 + const publicKey = mina.derivePublicKey(privateKey) + const publicKeyRaw = mina.publicKeyToRaw(publicKey) + // get transfer payload to sign + const payloadsResponse = await txPayloads( + publicKeyRaw, + publicKey, + to, + feeNano, + valueNano, + ) + + // sign and combine transfer payload + const combineResponse = await txCombine(payloadsResponse, privateKey) + const blob = combineResponse.signed_transaction + + // // get future transaction hash + const txHashResponse = await txHash(blob) + const hash = txHashResponse.transaction_identifier.hash + + // submit transaction. this call will fail if tx is not in mempool + await txSubmit(blob) + // wait for transaction confirmation: + // for that, track blocks until we meet our transaction in the last one + let latestBlock = (await networkStatus()).current_block_identifier.index + while (true) { + // check if our transaction exists in the latest block + const txs = (await waitForBlock(latestBlock)).block.transactions + const hashes = txs.map((tx: any) => tx.transaction_identifier.hash) + if (hashes.includes(hash)) { + break } - return hash -} - -// console.dir(await accountTransactions("B62qmVz7pPiLXPvz2nPkuK3K5akjrePAVtdBVMfeyixrccgqKTQte8K"), {depth: null}) - -// console.dir(await getTransaction("5JuYxWMjjygqiEz7oYCZicrXMcVcnptEAe2vXu6WqeN2qeNakJWe"), {depth: null}) - -// const hash = await send("EKE5nJtRFYVWqrCfdpqJqKKdt2Sskf5Co2q8CWJKEGSg71ZXzES7", "B62qmYYrf6RRHcGzJQXqY2Wz96LhaJrLuzvLNGwLBDKNvGA6jFCwZNa", 1000000000, 0) -// console.log(hash) + latestBlock += 1 + } + return hash +}