Create transaction

Hi

What do I have to do to hash the transaction data using the Javascript SDK? I am using the 10.16.0 version of NodeJS.

As you can see in the screenshot below, I think I’m creating transaction hash using TxBuilder. But I didn’t define any secretKey information. Is this a problem?

1 Like

Is there any reason that you try to build the transaction yourself instead of using the provided .spend() function?

I’ll ping one of our JS-SDK devs, as they will be better to help you.

@sistemkoin-mahsum Hey,
As i can see you already prepare the hash for spend transaction, the next step will be to wrap this transaction into signedTx which require the secretKey to produce the signature.
To do that you need to init MemoryAccount stamp and use signTransaction fn.
This is the implementation of this fn

/**
 * Sign encoded transaction
 * @instance
 * @category async
 * @rtype (tx: String) => tx: Promise[String], throws: Error
 * @param {String} tx - Transaction to sign
 * @param {Object} opt - Options
 * @return {String} Signed transaction
 */
async function signTransaction (tx, opt = {}) {
  const networkId = this.getNetworkId()
  const rlpBinaryTx = Crypto.decodeBase64Check(Crypto.assertedType(tx, 'tx'))
  // Prepend `NETWORK_ID` to begin of data binary
  const txWithNetworkId = Buffer.concat([Buffer.from(networkId), rlpBinaryTx])

  const signatures = [await this.sign(txWithNetworkId, opt)]
  return buildTx({ encodedTx: rlpBinaryTx, signatures }, TX_TYPE.signed).tx
}

I’m getting below error while trying your recommended action.

Before that i used spend function but i got 404 not found error instead.

can you try to narrow your code down to the essential part that creates the error, I can’t really see what wrong, eventually there is some issue how you implement the MemoryAccount.

        let accountMemory = MemoryAccount({
            keypair: {
                secretKey: data.from.privateKey,
                publicKey: data.from.publicKey || data.from.address
            },
            networkId: 'aet_ua'
        });
        let address = await accountMemory.address();

The error occurs when the MemoryAccount function is called. I guess when calling MemoryAccount function, publicKey is not defined in “const secrets = new WeakMap()”. In the first screenshot below, you can see the line where the error occurred. In the example in the second screenshot, you can see the output of the MemoryAccount() function. Output does not contain keypair information.

Screenshoot 1


Screenshoot 2
image

1 Like

can you try just using the Universal stamp of the sdk and a simplified keypair, where you don’t use memory account, just pass keypair as object directly to the sdk initialization?

also for testnet the networkId needs to be ae_uat.

Thank you!

Please double check your params from here

MemoryAccount({
            keypair: {
                secretKey: data.from.privateKey,
                publicKey: data.from.publicKey || data.from.address
            },
            networkId: 'aet_ua'
        });

Make sure that keypair.secretKey is hex string and keypair.publicKey is a ak_ prefixed string.

@sistemkoin-mahsum Can you please also log your data.from object.

@nduchak The parameters are correct. publicKey starts with “ak_”. But because I tried to get the private key value from the wrong property, an error occurred. I’d fix the problem.

Now I’ve mentioned above with the error 404 occurs. Error :

Error: Request failed with status code 404
    at createError (/projects/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/projects/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/projects/node_modules/axios/lib/adapters/http.js:237:11)
    at IncomingMessage.emit (events.js:203:15)
    at endReadableNT (_stream_readable.js:1129:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

Request:

{
  "url": "http://mynode:3013/v2/api",
  "method": "get",
  "headers": {
    "Accept": "application/json, text/plain, */*",
    "User-Agent": "axios/0.19.0"
  },
  "transformRequest": [
    null
  ],
  "transformResponse": [
    null
  ],
  "timeout": 0,
  "xsrfCookieName": "XSRF-TOKEN",
  "xsrfHeaderName": "X-XSRF-TOKEN",
  "maxContentLength": -1
}

Debug:

The error was from the URL. I fixed the URL. Now the error I mentioned below occurs.

ReferenceError: window is not defined
    at Object.init (/projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:153914)
    at /projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:76239
    at u (/projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:16715)
    at Generator._invoke (/projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:16503)
    at Generator.t.(anonymous function) [as next] (/projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:17137)
    at n (/projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:2050)
    at c (/projects/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:2260)
    at process._tickCallback (internal/process/next_tick.js:68:7)

I’m creating the Wallet function constant as follows.

const Wallet = require('@aeternity/aepp-sdk').Wallet;

Does anyone have any idea about the problem?

@sistemkoin-mahsum Just use Universal stamp instead of Wallet. Wallet works only in browser.

Is there an example of creating a transaction using Universal?

const client = await Universal({...});
await client.spend(amount, recipient);

Hi @piwo

The error occurs when I run this example.

Code

let universalConfig = {
    url: "http://MY_NODE_URL:3013/",
    internalUrl: "http://MY_NODE_URL:3013/",
    keypair: {
        publicKey: "my_public_key",
        secretKey: "my_secret_key"
    },
    networkId: 'ae_ua',
    nativeMode: true
};
const ae = await Universal(universalConfig);
let amount = "500000000000000000"; // 0.5 AE
let txID = await ae.spend(amount, data.to.publicKey || data.to.address);

Error

{
    "code": "Error",
    "message": "While calling postTransaction (body), POST to http://MY_NODE_URL:3013/v2/transactions failed with 400: Invalid tx",
    "stack": "Error: While calling postTransaction (body), POST to http://MY_NODE_URL:3013/v2/transactions failed with 400: Invalid tx\n    at Object.<anonymous> (/MY_PROJECT_DIR/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:93079)\n    at u (/MY_PROJECT_DIR/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:16715)\n    at Generator._invoke (/MY_PROJECT_DIR/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:16503)\n    at Generator.t.(anonymous function) [as throw] (/MY_PROJECT_DIR/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:17137)\n    at n (/MY_PROJECT_DIR/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:2050)\n    at s (/MY_PROJECT_DIR/node_modules/@aeternity/aepp-sdk/dist/aepp-sdk.js:1:2296)\n    at process._tickCallback (internal/process/next_tick.js:68:7)"
}

what network_id does your MY_NODE_URL run? for testnet you need to specify ae_uat (instead of ae_ua as in your post here)

How can I get network_id information in my node?
I am not using Testnet. Just trying to create a transaction in my own node?

You can go to http://MY_NODE_URL:3013/v2/status to know your network id