vechain / vechain-sdk-js

The official JavaScript SDK for VeChain.
22 stars 6 forks source link

💡 [REQUEST] - Improve serverless (especially CloudFlare) support #830

Closed ifavo closed 5 days ago

ifavo commented 3 months ago

Summary

My personal setup involves CloudFlare Workers a lot to create APIs or Vechain interaction with a very low effort. To enable transaction building with connex I have a stripped version of the thor-devkit that runs in node_compat (NodeJS compatibility) mode.

I would like to use the SDK within CloudFlare Workers in compatibility mode as well without creating a stripped version to:

  1. Build transaction objects
  2. Sign transactions
  3. Interact with the Node-APIs

Ideas to create the compatibility are:

  1. Use global fetch or allow injection of fetch function
  2. Dynamically import modules, like events on demand instead

Basic Example

  1. Create a new CloudFlare Worker using npx wrangler generate sdk-cf
  2. Add @vechain/sdk-network to it using npm install --save @vechain/sdk-network @vechain/sdk-core
  3. Create a thor client in the worker using ThorClient.fromUrl('https://testnet.vechain.org')
  4. Test the Worker by using wrangler dev or if you have a CloudFlare account use wrangler deploy
    • It will fail to start.
    • Optimal Results would be a CloudFlare Worker that can use the SDK instantly without enable Node Compatibility in the next step.
  5. Add node_compat = true to the wrangler.toml to enable NodeJS compatibility
  6. Test the Worker by using wrangler dev or if you have a CloudFlare account use wrangler deploy

Using this simplified index.ts:

import { ThorClient } from "@vechain/sdk-network";
export default {
    async fetch(
    ): Promise<Response> {
        const thor = ThorClient.fromUrl('https://testnet.vechain.org')
        const block = await thor.blocks.getBestBlockRef()
        return new Response(block);
    },
};
victhorbi commented 3 weeks ago

Hello @ifavo , With node_compat enabled, are you able to run the worker?

ifavo commented 3 weeks ago

No it won't.

ifavo commented 6 days ago

🥳 reading works, signing fails with:

✘ [ERROR]   Error: crypto.getRandomValues must be defined

I've used the following example:

        const clauses = [
            clauseBuilder.transferVET(
                '0x7567d83b7b8d80addcb281a71d54fc7b3364ffed', 0
            )
        ];

        // 2 - Calculate intrinsic gas of clauses
        const gas = TransactionUtils.intrinsicGas(clauses);

        // 3 - Body of transaction
        const body = {
            chainTag: networkInfo.mainnet.chainTag,
            blockRef: '0x0000000000000000',
            expiration: 0,
            clauses,
            gasPriceCoef: 128,
            gas,
            dependsOn: null,
            nonce: 12345678
        };

        // Create private key
        const privateKey = secp256k1.generatePrivateKey();

        // 4 - Sign transaction
        const signedTransaction = TransactionHandler.sign(
            body,
            Buffer.from(privateKey)
        );

        // 5 - Encode transaction
        const encodedRaw = signedTransaction.encoded;

        // 6 - Decode transaction
        const decodedTx = TransactionHandler.decode(encodedRaw, true);
        return new Response(JSON.stringify(decodedTx))

could you enable this too?

ifavo commented 6 days ago

I've opened a new issue: https://github.com/vechain/vechain-sdk-js/issues/1095

From my perspective we can close this issue, because it did not contain the signing as requirement.