near-api-js icon indicating copy to clipboard operation
near-api-js copied to clipboard

`i128` fields only accept `number` types on functioncall argument serialization

Open mgild opened this issue 3 years ago • 8 comments

Describe the bug When you want to pass an i128 field to functionCall as a param in near-api-js, the field only accepts the number type, problematic for reporting high precision numbers

To Reproduce Pass an i128 field as a parameter and call the function using near-api-js

Expected behavior The field should accept a stringified version of the number of BN.js to accept large ints

Screenshots If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information): MacOs 12.5.1

Additional context Add any other context about the problem here.

mgild avatar Aug 24 '22 17:08 mgild

Can you please share an example of what you were trying to call? Thanks.

ryancwalsh avatar Sep 20 '22 21:09 ryancwalsh

Does https://docs.near.org/tools/near-api-js/quick-reference#call-contract help?

ryancwalsh avatar Sep 20 '22 21:09 ryancwalsh

Hey @mgild, Please provide more information regarding this issue. Specifically:

  • the call you are making (with parameters methodName, args, gas, deposit )
  • error message you are getting

Please see reference to the FunctionCall implementation: https://github.com/near/near-api-js/blob/96785cb/packages/near-api-js/src/transaction.ts#L38

kenobijon avatar Sep 21 '22 09:09 kenobijon

Sure thing, the function prototype I am calling below:

#[derive(Default, Clone, BorshSerialize, BorshDeserialize, Serialize, Deserialize)]
pub struct AggregatorSaveResult {
    pub aggregator_key: Uuid,
    pub oracle_idx: u32,
    pub error: bool,
    pub value: SwitchboardDecimal,
    pub jobs_checksum: [u8; 32],
    pub min_response: SwitchboardDecimal,
    pub max_response: SwitchboardDecimal,
}
#[derive(
    Default,
    Debug,
    Copy,
    Clone,
    Eq,
    PartialEq,
    BorshDeserialize,
    BorshSerialize,
    Serialize,
    Deserialize,
)]
pub struct SwitchboardDecimal {
    pub mantissa: i128,
    pub scale: u32,
}
pub fn aggregator_save_result(&mut self, ix: AggregatorSaveResult);

How I am calling:

functionCall(
      "aggregator_save_result",
      {
        ix: {
          aggregator_key: [...this.address],
          oracle_idx: 0,
          error: false,
          value: { mantissa: 0, scale: 0}, // MANTISSA SHOULD BE BN, not number type!
          jobs_checksum: [...jobsChecksum],
          min_response: { mantissa: 0, scale: 0}, // MANTISSA SHOULD BE BN, not number type!
          max_response: { mantissa: 0, scale: 0}, // MANTISSA SHOULD BE BN, not number type!
        },
      },
      DEFAULT_FUNCTION_CALL_GAS,
      new BN(0)
    );

mgild avatar Sep 21 '22 12:09 mgild

If I try to use a BN for mantissa, I recieve: Smart contract panicked: panicked at 'Failed to deserialize input from JSON.: Error("invalid number", line: 1, column: 314)', src/lib.rs:47:1

mgild avatar Sep 21 '22 12:09 mgild

Same error when trying to use string for mantissa

mgild avatar Sep 21 '22 12:09 mgild

Using near_sdk::json_types::I128 allows you to pass in larger values as strings

kenobijon avatar Sep 21 '22 14:09 kenobijon

@mgild Ken and I were writing at the same time. Maybe his answer is what you need.

Otherwise, the reason I pointed to https://docs.near.org/tools/near-api-js/quick-reference#call-contract is because it gives an example like:

await contract.method_name(
  {
    callbackUrl: 'https://example.com/callback', // callbackUrl after the transaction approved (optional)
    meta: 'some info', // meta information NEAR Wallet will send back to the application. `meta` will be attached to the `callbackUrl` as a url search param
    args: {
        arg_name: "value" // argument name and value - pass empty object if no args required
    },
    gas: 300000000000000, // attached GAS (optional)
    amount: 1000000000000000000000000 // attached deposit in yoctoNEAR (optional)
  }
);

If you're using near-api-js, I'm curious if using that approach instead of functionCall( would help.

ryancwalsh avatar Sep 21 '22 14:09 ryancwalsh