Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add encode call data #1

Merged
merged 13 commits into from
Mar 22, 2024
25 changes: 25 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Build and Test

on:
pull_request:
branches: [ main ]
workflow_dispatch:

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm run compile
- run: npm test
74 changes: 74 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
push:
branches: [ "main" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
schedule:
- cron: '32 10 * * 2'

jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write

strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

steps:
- name: Checkout repository
uses: actions/checkout@v3

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality


# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

# - run: |
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
with:
category: "/language:${{matrix.language}}"
39 changes: 39 additions & 0 deletions .github/workflows/publish-alpha-beta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Publish (alpha / beta)

on:
workflow_dispatch:
inputs:
channel:
type: choice
description: NPM channel
options:
- alpha
- beta

permissions:
contents: write

jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 18
registry-url: https://registry.npmjs.org/

- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_TAG=v$(node -p "require('./package.json').version")
gh release create --prerelease $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes

- run: npm ci
- run: npm test

- name: Publish to npmjs
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish --access=public --tag=${{ github.event.inputs.channel }}
32 changes: 32 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Publish

on:
workflow_dispatch:

permissions:
contents: write

jobs:
publish-npm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 18
registry-url: https://registry.npmjs.org/

- name: Create release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
RELEASE_TAG=v$(node -p "require('./package.json').version")
gh release create $RELEASE_TAG --target=$GITHUB_SHA --title="$RELEASE_TAG" --generate-notes

- run: npm ci
- run: npm test

- name: Publish to npmjs
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
run: npm publish --access=public
56 changes: 56 additions & 0 deletions helpers/encodeCallData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import BigNumber from "bignumber.js";
import { numberToPaddedHex } from "@multiversx/sdk-core/out/utils.codec";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe import directly from @multiversx/sdk-core/utils.codec, not from the /out dir.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TS2307: Cannot find module  @multiversx/sdk-core/utils.codec  or its corresponding type declarations.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. We'll keep that in mind.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, feel free to:

export function numberToPaddedHex(value: bigint | number | BigNumber.Value) {
    let hexableNumber: { toString(radix?: number): string };

    if (typeof value === "bigint" || typeof value === "number") {
        hexableNumber = value;
    } else {
        hexableNumber = new BigNumber(value);
    }

    const hex = hexableNumber.toString(16);
    return zeroPadStringIfOddLength(hex);
}

export function zeroPadStringIfOddLength(input: string): string {
    input = input || "";

    if (input.length % 2 == 1) {
        return "0" + input;
    }

    return input;
}


const uint32ArgBytes = 8
const uint64ArgBytes = 16
const DataPresentProtocolMarker = "0x01"
/**
* Encodes call data for the deposit function with simplified argument handling.
* Automatically attempts to detect and encode integers and strings.
*
* @param {string} endpointName - The name of the endpoint for the cross-chain call.
* @param {number} gasLimit - The gas limit for the cross-chain call.
* @param {any[]} args - The arguments for the cross-chain call, assumed to be strings or numbers.
* @returns {string} The encoded callData string.
*/
export function encodeCallData(endpointName: string, gasLimit: number, args: any[]): string {
let callData = DataPresentProtocolMarker;
callData = addEndpointName(callData, endpointName);
callData = addGasLimit(callData, gasLimit);
callData = addArgs(callData, args);

return callData;
}

export function addEndpointName(callData: string, endpointName: string): string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only for internal use and tests, right (as the ones below)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

const endpointNameBuffer = Buffer.from(endpointName, 'utf8');
const endpointNameLength = new BigNumber(endpointNameBuffer.length).toString(16).padStart(uint32ArgBytes, '0');
const endpointNameHex = endpointNameBuffer.toString('hex');
return callData + endpointNameLength + endpointNameHex;
}

export function addGasLimit(callData: string, gasLimit: number): string {
const gasLimitHex = new BigNumber(gasLimit).toString(16).padStart(uint64ArgBytes, '0');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So only nested encoding, but maybe this is the context, all right.

return callData + gasLimitHex;
}

export function addArgs(callData: string, args: any[]): string {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you are referring sdk-core. Perhaps BinaryCodec would have helped a bit?

https://github.com/multiversx/mx-sdk-js-core/blob/main/src/smartcontracts/codec/binary.spec.ts#L210

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the time being will let it like this

const numArgsHex = new BigNumber(args.length).toString(16).padStart(uint32ArgBytes, '0');
let encodedArgs = '';
args.forEach(arg => {
let argHex, argLengthHex;
if (typeof arg === 'number' || (!isNaN(arg) && !isNaN(parseFloat(arg)))) {
// Treat as number and convert to padded hex
argHex = numberToPaddedHex(arg);
} else if (typeof arg === "string") {
// Treat as string
const argBuffer = Buffer.from(arg, 'utf8');
argHex = argBuffer.toString('hex');
} else {
throw new Error(`Unsupported argument type: ${typeof arg}`);
}
argLengthHex = new BigNumber(argHex.length / 2).toString(16).padStart(uint32ArgBytes, '0');
encodedArgs += argLengthHex + argHex;
});
return callData + numArgsHex + encodedArgs;
}
1 change: 1 addition & 0 deletions helpers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { encodeCallData } from './encodeCallData';
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { encodeCallData } from "./helpers/encodeCallData";
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
Loading
Loading