near-api-js
near-api-js copied to clipboard
`i128` fields only accept `number` types on functioncall argument serialization
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.
Can you please share an example of what you were trying to call? Thanks.
Does https://docs.near.org/tools/near-api-js/quick-reference#call-contract help?
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
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)
);
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
Same error when trying to use string for mantissa
Using near_sdk::json_types::I128 allows you to pass in larger values as strings
@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.