Web SDK: Cannot convert undefined to a BigInt

Hey guys, I’ve been stuck on this problem for so long. I’m trying to create a simple trace object on my existing contract on ccd testnet but getting this error from concordium serializationHelpers:

TypeError: Cannot convert undefined to a BigInt
    at DataView.setBigUint64 (<anonymous>)
    at encodeWord64 (\node_modules\@concordium\web-sdk\src\serializationHelpers.ts:67:10)
    at UpdateContractHandler.serialize (\node_modules\@concordium\web-sdk\src\accountTransactions.ts:283:34)
    at serializeAccountTransactionPayload (\node_modules\@concordium\web-sdk\src\serialization.ts:136:57)
    at ConcordiumGRPCNodeClient.sendAccountTransaction (ˇ\node_modules\@concordium\web-sdk\src\grpc\GRPCClient.ts:294:28)
    at TraceService.createTrace (\src\concordium\concordium.service.ts:182:40)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at ProductService.create (\src\product\product.service.ts:48:26)
    at async \node_modules\@nestjs\core\router\router-execution-context.js:46:28
    at async \node_modules\@nestjs\core\router\router-proxy.js:9:17

this is my createTrace function:

 async createTrace(params: {
    entityType: 'Product' | 'Review' | 'Tag';
    typeId: string;
    changeId?: string;
  }) {
    try {
      if (!this.SDK || !this.client) {
        throw new Error('Service not properly initialized');
      }

      const adminAddress = process.env.CONCORDIUM_ADMIN_ADDRESS;
      if (!adminAddress) {
        throw new Error(
          'Missing CONCORDIUM_ADMIN_ADDRESS environment variable',
        );
      }

      const parameters = {
        entity_type:
          params.entityType === 'Product'
            ? 0
            : params.entityType === 'Review'
              ? 1
              : 2,
        type_id: params.typeId,
        change_id: params.changeId ? { Some: params.changeId } : { None: null },
      };

      const address = this.SDK.AccountAddress.fromBase58(adminAddress);
      const nonceResponse = await this.client.getNextAccountNonce(address);

      const contractAddr = {
        index: BigInt(10532),
        subindex: BigInt(0),
      };

      // Convert header values
      const header = {
        expiry: BigInt(Math.floor(Date.now() / 1000) + 3600),
        nonce: BigInt(nonceResponse.nonce),
        sender: address,
      };

      // Create UpdateContract payload
      const updatePayload = {
        address: contractAddr,
        amount: BigInt(0),
        receiveName: this.SDK.ReceiveName.fromString('trace.create_trace'),
        maxContractExecutionEnergy: BigInt(30000),
        message: Buffer.from(JSON.stringify(parameters)),
      };

      // Create the full transaction
      const transaction = {
        header,
        payload: updatePayload,
        type: this.SDK.AccountTransactionType.Update,
      };

      // Sign and send
      const signatures: any[] = [];
      const result = await this.client.sendAccountTransaction(
        transaction,
        signatures,
      );

      if (!result) {
        throw new Error('Transaction rejected by node');
      }

      return result;
    } catch (error) {
      this.logger.error('Trace creation failed:', {
        error: error.message,
        stack: error.stack,
        params,
      });
      throw error;
    }
  }

this is params of the function

pub struct CreateTraceParams {
    pub entity_type: EntityType,
    pub type_id: String,
    pub change_id: Option<String>,
}

and this is params I’m sending to create_trace function

  "params": {
    "entityType": "Product",
    "typeId": "cm5nrp5j50001l3gymf0dh4yu",
    "changeId": "cm5p3aig80001srgmxny0icch"
  }

Does anyone maybe see the mistake?

Hi there

The message needs to be constructed using a schema for the smart contract using serializeUpdateContractParameters.

You can also generate a smart contract client using ccd-js-gen which will deal with most of this, like we do in our example here.