Serial of execution as JSON with multiple canisters

Hi, I don’t know is anyone work on this topic before. But I what if I define of serial of actions like

  1. deposit token A to canister X
  2. call swap method A to B in X
  3. call withdraw B from X

Normally If I work with this flow I have to use three of Actors

a = createTokenAActor("aaaaa-aaaaa-aa...-cai")
b = createTokenBActor("bbbbb-bbbbb-bb...cai")
x = createPoolXActor("xxxxx-xxxxx-xx..cai")

a.transfer(x)
x.swap(a,b)
x.withdraw(b)

what if I define it as a JSON object like

{
  actions: [
    {
      "type": "call",
      "method": "icrc1_transfer",
      "source": "aaaaa-aaaaa-aa...-cai",
      "destinaion": "xxxxx-xxxxx-xx..cai",
      "amount": 1000
    },
    {
      "type": "call",
      "method": "swap",
      "source": "xxxxx-xxxxx-xx..cai",
      "args": {
        "pair": "aaaaa-aaaaa-aa...-cai/bbbbb-bbbbb-bb...cai"
      }
    },
    {
      "type": "call",
      "method": "withdraw",
      "source": "xxxxx-xxxxx-xx..cai",
      "args": {
        "token": "bbbbb-bbbbb-bb...cai"
      }
    }
  ]
}

then parse it with the code and execute it by order. So it can reduce time of coding and also can benefit for predefine transaction made by developers and then share it.

What do you think why should we not have this?

I’m not always in favor of more abstraction, but I like this idea. You would need to provide more detail for it to be understood because from reading this it seems to be an oversimplification.

yeah, It just an abstract that I made out of but, I wonder why nobody thinking about this before :smiley:. I’m just asking for ideal making one kinda of this

With this ability I think it can be huge success if we made on library like this

Hello,

To streamline your interaction with canisters on the Internet Computer (IC), you can leverage the createReactorCore function provided by @ic-reactor/core. This core module serves as the main entry point for managing actors and agents, ensuring efficient communication with canisters.

Example Using createReactorCore

Let’s illustrate how you can use createReactorCore with an example that aligns with your proposed JSON-based action sequence:

import { createReactorCore } from "@ic-reactor/core"
import { candid, canisterId, idlFactory } from "./declarations/candid"

type Candid = typeof candid

// Initialize ReactorCore instance for managing actors
const { queryCall, updateCall, login, getPrincipal } =
  createReactorCore<Candid>({
    canisterId,
    idlFactory,
    withProcessEnv: true, // Utilize process.env.DFX_NETWORK
  })

// Define a function to execute a sequence of actions
async function executeSequence(actions) {
  try {
    // Iterate through each action in the sequence
    for await (const action of actions) {
      if (action.type === "call") {
        // Perform the call based on the method specified in the action
        const { call: actionCall } = updateCall({
          canisterId: action.source, // Include canisterId in updateCall
          functionName: action.method,
          args: action.args || [], // Pass arguments if provided
        })

        // Execute the action call
        const result = await actionCall()
        console.log(`Action "${action.method}" executed with result:`, result)
      } else {
        console.warn(`Unsupported action type "${action.type}"`)
      }
    }
  } catch (error) {
    console.error("Error executing actions:", error)
  }
}

// Example sequence of actions based on your JSON proposal
const actions = [
  {
    type: "call",
    method: "icrc1_transfer",
    source: "aaaaa-aaaaa-aa...-cai",
    destination: "xxxxx-xxxxx-xx..cai",
    amount: 1000,
  },
  {
    type: "call",
    method: "swap",
    source: "xxxxx-xxxxx-xx..cai",
    args: {
      pair: "aaaaa-aaaaa-aa...-cai/bbbbb-bbbbb-bb...cai",
    },
  },
  {
    type: "call",
    method: "withdraw",
    source: "xxxxx-xxxxx-xx..cai",
    args: {
      token: "bbbbb-bbbbb-bb...cai",
    },
  },
]

// Execute the defined sequence of actions
executeSequence(actions)

Explanation

  • Usage of createReactorCore: Initializes the core module for managing canister interactions.
  • Executing Action Sequence: Demonstrates how to loop through a predefined sequence of actions using for await, ensuring each action completes before proceeding to the next.
  • Including canisterId in updateCall: Ensures that each method call is directed to the correct canister based on the provided canisterId.

This approach provides a structured and efficient way to manage complex transaction flows on the Internet Computer. For further details and advanced usage scenarios, refer to the official documentation.

Best regards,

Behrad

2 Likes