EOSIO / eosjs

General purpose library for the EOSIO blockchain.
http://eosio.github.io/eosjs
MIT License
1.43k stars 463 forks source link

how to get a offline serializedTransaction without set a node url before sign? #616

Closed lansehuiyi6 closed 4 years ago

lansehuiyi6 commented 4 years ago

Version of EOSJS eosjs@20.0.2

Describe the bug How can i get the serializedTransaction without set the node url? If i want to do a colder wallet.

const { Api, JsonRpc } = require('eosjs');
const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig');
const signatureProvider = new JsSignatureProvider(privateKeys);
const rpc = new JsonRpc('', { fetch });
const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });
  let transaction = packed_tx.transaction;
  transaction = { ...transaction, actions: await api.serializeActions(transaction.actions) };
  const serializedTransaction = api.serializeTransaction(transaction);

let packed_tx = { chain_id: 'e70aaab8997e1dfce58fbfac80cbbb8fecec7b99cf982a9444273cbc64c41473',
  transaction:
   { expiration: '2019-04-28T11:20:58',
     ref_block_num: 26609,
     ref_block_prefix: 934109041,
     max_net_usage_words: 0,
     max_cpu_usage_ms: 0,
     delay_sec: 0,
     context_free_actions: [],
     actions: [{
      account: 'eosio.token',
      name: 'transfer',
      authorization: [{
        actor: 'aarontestnet',
        permission: 'active',
      }],
      data: {
        from: 'aarontestnet',
        to: 'htlceostest1',
        quantity: '0.0001 EOS',
        memo: '',
      },
    }],
     transaction_extensions: [] } }
console.log(serializedTransaction);

But i got the error: err is { TypeError: fetching abi for eosio.token: Only absolute URLs are supported at getNodeRequestOptions (/home/lizhan/wanglu/demo/js_shadow2/node_modules/node-fetch/lib/index.js:1299:9) at /home/lizhan/wanglu/demo/js_shadow2/node_modules/node-fetch/lib/index.js:1404:19 at new Promise () at fetch (/home/lizhan/wanglu/demo/js_shadow2/node_modules/node-fetch/lib/index.js:1401:9) at JsonRpc. (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:99:46) at step (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:36:23) at Object.next (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:17:53) at /home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:11:71 at new Promise () at __awaiter (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:7:12) isFetchError: true }

At version eosjs@16.0.9, i can get the serializedTransaction as follows:

    const Transaction = eos.fc.structs.transaction;
    const buf = Fcbuffer.toBuffer(Transaction, packed_tx.transaction);
    const chain_id_buf = new Buffer(chain_id, 'hex')
    const sign_buf = Buffer.concat([chain_id_buf, buf, new Buffer(new Uint8Array(32))])

Then i can get the sig with ecc.sign(sign_buf, pvt), but at version eosjs@20.0.2, how can i get a sign_buf before use the signProvider to sign?

tbfleming commented 4 years ago

You can populate the abi cache with:

api.cachedAbis.set(contractName, {abi, rawAbi: null});
tbfleming commented 4 years ago

You need to serialize the action data before serializing that transaction. Easiest way is to use the transact method. To stop it from trying to use the rpc api, set api.chainId and populate the abi cache as above. Use transact's broadcast=false option and don't set its blocksBehind option.

lansehuiyi6 commented 4 years ago

broadcast


const { Api, JsonRpc } = require('eosjs');
const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig');
const fetch = require('fetch');
const { TextEncoder, TextDecoder } = require('text-encoding');
const privateKeys = ['************************'];
const signatureProvider = new JsSignatureProvider(privateKeys);

let eosAbi = {"version": "eosio::abi/1.1", "types": [{"new_type_name": "time_t", "type": "uint32"} ], "structs": [{"name": "asset_t", "base": "", "fields": [{"name": "balance", "type": "asset"} ] }, {"name": "debt_t", "base": "", "fields": [{"name": "id", "type": "uint64"}, {"name": "pid", "type": "uint64"}, {"name": "npid", "type": "uint64"}, {"name": "quantity", "type": "asset"}, {"name": "lockedTime", "type": "time_t"}, {"name": "beginTime", "type": "time_point_sec"}, {"name": "status", "type": "string"}, {"name": "xHash", "type": "checksum256"} ] }, {"name": "fee_t", "base": "", "fields": [{"name": "fee", "type": "asset"} ] }, {"name": "inlock", "base": "", "fields": [{"name": "user", "type": "name"}, {"name": "htlc", "type": "name"}, {"name": "quantity", "type": "asset"}, {"name": "memo", "type": "string"} ] }, {"name": "inrdm", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "inredeem", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "x", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "inrevoke", "base": "", "fields": [{"name": "user", "type": "name"}, {"name": "xHash", "type": "string"} ] }, {"name": "kk", "base": "", "fields": [{"name": "x", "type": "string"} ] }, {"name": "leftlocktime", "base": "", "fields": [{"name": "from", "type": "name"}, {"name": "table", "type": "name"}, {"name": "xHash", "type": "string"} ] }, {"name": "lkdebt", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "lockdebt", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "quantity", "type": "asset"}, {"name": "npk", "type": "string"}, {"name": "xHash", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "outlk", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "outlock", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "user", "type": "name"}, {"name": "quantity", "type": "asset"}, {"name": "xHash", "type": "string"}, {"name": "wanAddr", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "outredeem", "base": "", "fields": [{"name": "user", "type": "name"}, {"name": "x", "type": "string"} ] }, {"name": "outrevoke", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "xHash", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "outrvk", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "pk_t", "base": "", "fields": [{"name": "id", "type": "uint64"}, {"name": "pkHash", "type": "checksum256"}, {"name": "pk", "type": "string"} ] }, {"name": "rdmdebt", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "redeemdebt", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "x", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "regsig", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "code", "type": "name"}, {"name": "action", "type": "name"} ] }, {"name": "removepk", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "pk", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "revokedebt", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "xHash", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "rmpk", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "rvkdebt", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "signature_t", "base": "", "fields": [{"name": "code", "type": "name"}, {"name": "action", "type": "name"} ] }, {"name": "transfer_t", "base": "", "fields": [{"name": "id", "type": "uint64"}, {"name": "pid", "type": "uint64"}, {"name": "quantity", "type": "asset"}, {"name": "user", "type": "name"}, {"name": "lockedTime", "type": "time_t"}, {"name": "beginTime", "type": "time_point_sec"}, {"name": "status", "type": "string"}, {"name": "xHash", "type": "checksum256"}, {"name": "wanAddr", "type": "string"} ] }, {"name": "truncate", "base": "", "fields": [{"name": "table", "type": "name"}, {"name": "scope", "type": "string"} ] }, {"name": "unregsig", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "code", "type": "name"} ] }, {"name": "updatepk", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "npk", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] }, {"name": "updatesig", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "code", "type": "name"}, {"name": "nCode", "type": "name"}, {"name": "nAction", "type": "name"} ] }, {"name": "updtpk", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "wdr", "base": "", "fields": [{"name": "htlc", "type": "name"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "msg", "type": "string"}, {"name": "memo", "type": "string"} ] }, {"name": "withdraw", "base": "", "fields": [{"name": "storeman", "type": "name"}, {"name": "sym", "type": "string"}, {"name": "pk", "type": "string"}, {"name": "r", "type": "string"}, {"name": "s", "type": "string"} ] } ], "actions": [{"name": "inlock", "type": "inlock", "ricardian_contract": ""}, {"name": "inrdm", "type": "inrdm", "ricardian_contract": ""}, {"name": "inredeem", "type": "inredeem", "ricardian_contract": ""}, {"name": "inrevoke", "type": "inrevoke", "ricardian_contract": ""}, {"name": "kk", "type": "kk", "ricardian_contract": ""}, {"name": "leftlocktime", "type": "leftlocktime", "ricardian_contract": ""}, {"name": "lkdebt", "type": "lkdebt", "ricardian_contract": ""}, {"name": "lockdebt", "type": "lockdebt", "ricardian_contract": ""}, {"name": "outlk", "type": "outlk", "ricardian_contract": ""}, {"name": "outlock", "type": "outlock", "ricardian_contract": ""}, {"name": "outredeem", "type": "outredeem", "ricardian_contract": ""}, {"name": "outrevoke", "type": "outrevoke", "ricardian_contract": ""}, {"name": "outrvk", "type": "outrvk", "ricardian_contract": ""}, {"name": "rdmdebt", "type": "rdmdebt", "ricardian_contract": ""}, {"name": "redeemdebt", "type": "redeemdebt", "ricardian_contract": ""}, {"name": "regsig", "type": "regsig", "ricardian_contract": ""}, {"name": "removepk", "type": "removepk", "ricardian_contract": ""}, {"name": "revokedebt", "type": "revokedebt", "ricardian_contract": ""}, {"name": "rmpk", "type": "rmpk", "ricardian_contract": ""}, {"name": "rvkdebt", "type": "rvkdebt", "ricardian_contract": ""}, {"name": "truncate", "type": "truncate", "ricardian_contract": ""}, {"name": "unregsig", "type": "unregsig", "ricardian_contract": ""}, {"name": "updatepk", "type": "updatepk", "ricardian_contract": ""}, {"name": "updatesig", "type": "updatesig", "ricardian_contract": ""}, {"name": "updtpk", "type": "updtpk", "ricardian_contract": ""}, {"name": "wdr", "type": "wdr", "ricardian_contract": ""}, {"name": "withdraw", "type": "withdraw", "ricardian_contract": ""} ], "tables": [{"name": "assets", "index_type": "i64", "key_names": [], "key_types": [], "type": "asset_t"}, {"name": "debts", "index_type": "i64", "key_names": [], "key_types": [], "type": "debt_t"}, {"name": "fees", "index_type": "i64", "key_names": [], "key_types": [], "type": "fee_t"}, {"name": "pks", "index_type": "i64", "key_names": [], "key_types": [], "type": "pk_t"}, {"name": "signer", "index_type": "i64", "key_names": [], "key_types": [], "type": "signature_t"}, {"name": "transfers", "index_type": "i64", "key_names": [], "key_types": [], "type": "transfer_t"} ], "ricardian_clauses": [], "error_messages": [], "abi_extensions": [], "variants": [] };

const rpc = new JsonRpc('', {fetch}); const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() }); api.cachedAbis.set('eosio.token', {eosAbi, rawAbi:null});

async function sendTransaction() { try { let actions = [{ account: 'eosio.token', name: 'transfer', authorization: [{ actor: 'aaron', permission: 'active', }], data: { from: 'aaron', to: 'aaron1', quantity: '0.0001 EOS', memo: '', }, }];

let result = await api.transact({
  actions: actions
}, {
  // blocksBehind: 3,
  // expireSeconds: 30,
  broadcast: false, 
  // sign: false
});
console.log(result); 

} catch (err) { console.log(err); } }


but i got the follow error:

{ TypeError: f is not a function
    at JsonRpc.<anonymous> (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:99:46)
    at step (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:36:23)
    at Object.next (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:17:53)
    at /home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:11:71
    at new Promise (<anonymous>)
    at __awaiter (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:7:12)
    at JsonRpc.fetch (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:92:16)
    at JsonRpc.<anonymous> (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:208:55)
    at step (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:36:23)
    at Object.next (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:17:53) isFetchError: true }
tbfleming commented 4 years ago
api.cachedAbis.set('eosio.token', {eosAbi, rawAbi:null});

This is missing the abi field. It doesn't expect a field named eosAbi.

Also, the abi you posted isn't eosio.token. It's a weird mangled mess from the sources of eosjs 16 that's not supported by 20.

The rpc object has a method to fetch the raw abi. You could save it in a file, but be careful since it's binary.

tbfleming commented 4 years ago

You should only need the binary if you're using jssig. Also, you didn't set api.chainId.

tbfleming commented 4 years ago

typo: you should not need the binary since you're using jssig.

lansehuiyi6 commented 4 years ago

typo: you should not need the binary since you're using jssig.

declare class JsSignatureProvider implements SignatureProvider {
    /** map public to private keys */
    keys: Map<string, ec.KeyPair>;
    /** public keys */
    availableKeys: string[];
    /** @param privateKeys private keys to sign with */
    constructor(privateKeys: string[]);
    /** Public keys associated with the private keys that the `SignatureProvider` holds */
    getAvailableKeys(): Promise<string[]>;
    /** Sign a transaction */
    sign({ chainId, requiredKeys, serializedTransaction, serializedContextFreeData }: SignatureProviderArgs): Promise<{
        signatures: string[];
        serializedTransaction: Uint8Array;
        serializedContextFreeData: Uint8Array;
    }>;
}

Refer to the above code about jssig, i only need chainid when i sign the serializedTransaction, yes? But before sign, chainid is needless?

lansehuiyi6 commented 4 years ago

typo: you should not need the binary since you're using jssig.

I've tried as you said.

const { Api, JsonRpc } = require('eosjs');
const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig');
const fetch = require('node-fetch');
const { TextEncoder, TextDecoder } = require('text-encoding');
    let signatureProvider = new JsSignatureProvider(["*******************"]);   // Your private key

async function get_rawabi_and_abi(account) {
  try {
    let endpoint = 'http://192.168.1.58:8888';
    let rpc = new JsonRpc(endpoint, { fetch })   // EOS http endpoint

    let api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder, textEncoder: new TextEncoder });

    let rawAbi = (await api.abiProvider.getRawAbi(account)).abi;
    let abi = (await api.abiProvider.get_abi(account)).abi;
    console.log("==================get_rawabi_and_abi==================");
    console.log(rawAbi);
    console.log(abi);

    let result = {
      accountName: account,
      rawAbi: rawAbi,
      abi: abi
    }
    return result;
  } catch (err) {
    console.log(err);
  }
}

async function main() {
  try {
    let result = await get_rawabi_and_abi('eosio.token');
    console.log(result);

    const rpc = new JsonRpc('http://should-never-be-called');
    const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });
    api.cachedAbis.set('eosio.token', {abi: result.abi, rawAbi:result.rawAbi});

    let abi = (await api.rpc.get_abi('eosio.token')).abi;
    console.log(abi);
  } catch (err) {
    console.log('err is', err);
  }
}
main();

This time i use eosjs20 to get the abi and rawAbi first. I set the abi and rawabi, then i retry to get abi back. But i still get the error as follow, i don't know, i suspect there should be one bug during this. I even didn't try to do the transact action.

err is { TypeError: f is not a function at JsonRpc. (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:99:46) at step (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:36:23) at Object.next (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:17:53) at /home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:11:71 at new Promise () at __awaiter (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:7:12) at JsonRpc.fetch (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:92:16) at JsonRpc. (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:130:55) at step (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:36:23) at Object.next (/home/lizhan/wanglu/demo/js_shadow2/node_modules/eosjs/dist/eosjs-jsonrpc.js:17:53) isFetchError: true }

bradlhart commented 4 years ago

Here's a solution. Not sure if you need the signing as well.


const { Api, JsonRpc } = require('eosjs');
const { JsSignatureProvider, PrivateKey } = require('eosjs/dist/eosjs-jssig');
const fetch = require('node-fetch');
const { TextEncoder, TextDecoder } = require('text-encoding');

const privateKeys = ['YOUR_PRIVATE_KEY']
const signatureProvider =
    new JsSignatureProvider(privateKeys);

const get_rawabi_and_abi = async (account) => {
    try {
        const endpoint = 'http://localhost:8888';
        const rpc = new JsonRpc(endpoint, { fetch });

        const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder, textEncoder: new TextEncoder });

        const rawAbi = (await api.abiProvider.getRawAbi(account)).abi;
        const abi = await api.rawAbiToJson(rawAbi);

        const result = {
            accountName: account,
            rawAbi,
            abi
        };
        return result;
    } catch (err) {
        console.log(err);
    }
}

const main = async () => {
    try {
        const chainId = 'chain-id';
        const abiObj = await get_rawabi_and_abi('eosio.token');

        const rpc = new JsonRpc('http://should-never-be-called');
        const api = new Api({ rpc, signatureProvider, textDecoder: new TextDecoder(), textEncoder: new TextEncoder(), chainId });
        api.cachedAbis.set('eosio.token', {abi: abiObj.abi, rawAbi: abiObj.rawAbi});

        const actions = [{
            account: 'eosio.token',
            name: 'transfer',
            authorization: [{
                actor: 'aaron',
                permission: 'active',
            }],
            data: {
                from: 'aaron',
                to: 'aaron1',
                quantity: '0.0001 EOS',
                memo: '',
            },
        }];

        const transaction = {
            actions,
            expiration: '2019-04-28T11:20:58',
            ref_block_num: 26609,
            ref_block_prefix: 934109041,
        };

        const result = await api.transact(transaction, { broadcast: false, sign: false });

        const abis = await api.getTransactionAbis(transaction);
        const requiredKeys = privateKeys.map((privateKey) => PrivateKey.fromString(privateKey).getPublicKey().toString());

        result.signatures = await signatureProvider.sign({
            chainId,
            requiredKeys,
            serializedTransaction: result.serializedTransaction,
            serializedContextFreeData: result.serializedContextFreeData,
            abis
        });

        console.log(result);
    } catch (err) {
        console.log('err is', err);
    }
}
main()
bradlhart commented 4 years ago

Please let me know if the above code does not work.

DarKWinGTM commented 3 years ago

Please let me know if the above code does not work.

Can I generate packed_trx from result.serializedTransaction ? Please help, we can do or not without "cleos convert pack_transaction" ?

bradlhart commented 3 years ago

eosjs-jsonrpc.ts has a function called arrayToHex that converts a serializedTransaction to a packed_trx. You can see how it's used in the push_transaction method. Unfortunately it is not an exported function so you will need to copy it to your code to use it.

DarKWinGTM commented 3 years ago

eosjs-jsonrpc.ts has a function called arrayToHex that converts a serializedTransaction to a packed_trx. You can see how it's used in the push_transaction method. Unfortunately it is not an exported function so you will need to copy it to your code to use it.

Thanks let me try. Do you have Brave wallet ? if it work i want to bye your coffee.

Updated : It working.

const arrayToHex = (data) => {
    let result = '';
    for (const x of data) {
        result += ('00' + x.toString(16)).slice(-2);
    }; return result;
};