-
Notifications
You must be signed in to change notification settings - Fork 95
Convert bigNumber to bigint #908
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
base: main
Are you sure you want to change the base?
Convert bigNumber to bigint #908
Conversation
Co-authored-by: joaquim.verges <[email protected]>
WalkthroughA new utility module for transforming BigNumber objects within data structures has been added. The backend wallet route now uses this utility to convert any BigNumber instances in incoming request payloads to stringified bigints before signing typed data. No changes were made to exported entity signatures or error handling. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant BackendRoute
participant Utils
Client->>BackendRoute: POST /sign-typed-data { value }
BackendRoute->>Utils: transformBigNumbers(value)
Utils-->>BackendRoute: transformedValue
BackendRoute->>BackendRoute: signTypedData(message=transformedValue)
BackendRoute-->>Client: Response (signed data)
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes ✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/server/routes/backend-wallet/sign-typed-data.ts
(3 hunks)src/shared/utils/bignumber.ts
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: the `getchecksumaddress` function in this codebase safely handles undefined/null values by accepting...
Learnt from: d4mr
PR: thirdweb-dev/engine#897
File: src/server/routes/backend-wallet/transfer.ts:15-0
Timestamp: 2025-06-09T23:37:07.373Z
Learning: The `getChecksumAddress` function in this codebase safely handles undefined/null values by accepting `val?: string | Address | null` and returning `Address | undefined`. It returns `undefined` when passed falsy values, so calling it on potentially undefined values like `accountFactoryAddress` does not cause runtime errors.
Applied to files:
src/server/routes/backend-wallet/sign-typed-data.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build
- GitHub Check: lint
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
src/shared/utils/bignumber.ts (2)
8-11
: LGTM! Interface correctly models BigNumber objects.The interface accurately represents the BigNumber object structure as described in the PR objectives.
16-25
: LGTM! Robust type guard implementation.The type guard properly validates all required properties and types, including null safety checks.
src/server/routes/backend-wallet/sign-typed-data.ts (3)
9-9
: LGTM! Import statement is correct.The import properly references the new utility function.
51-52
: LGTM! Proper placement of BigNumber transformation.The transformation is correctly applied to the value before signing typed data.
86-86
: LGTM! Correct usage of transformed value.The transformed value is properly passed as the message parameter to the signing function.
function bigNumberToStringifiedBigInt(bigNumberObj: BigNumberObject): string { | ||
// Convert hex string to bigint, then to string | ||
return BigInt(bigNumberObj.hex).toString(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add error handling for invalid hex strings.
The BigInt()
constructor will throw a SyntaxError
if the hex string is malformed. This could cause runtime errors when processing user input.
function bigNumberToStringifiedBigInt(bigNumberObj: BigNumberObject): string {
- // Convert hex string to bigint, then to string
- return BigInt(bigNumberObj.hex).toString();
+ try {
+ // Convert hex string to bigint, then to string
+ return BigInt(bigNumberObj.hex).toString();
+ } catch (error) {
+ throw new Error(`Invalid hex string in BigNumber object: ${bigNumberObj.hex}`);
+ }
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
function bigNumberToStringifiedBigInt(bigNumberObj: BigNumberObject): string { | |
// Convert hex string to bigint, then to string | |
return BigInt(bigNumberObj.hex).toString(); | |
} | |
function bigNumberToStringifiedBigInt(bigNumberObj: BigNumberObject): string { | |
try { | |
// Convert hex string to bigint, then to string | |
return BigInt(bigNumberObj.hex).toString(); | |
} catch (error) { | |
throw new Error(`Invalid hex string in BigNumber object: ${bigNumberObj.hex}`); | |
} | |
} |
🤖 Prompt for AI Agents
In src/shared/utils/bignumber.ts around lines 30 to 33, the function
bigNumberToStringifiedBigInt directly converts a hex string to BigInt without
handling potential errors. To fix this, wrap the BigInt conversion in a
try-catch block to catch SyntaxError exceptions caused by malformed hex strings,
and handle the error gracefully, such as returning a default value or throwing a
custom error with a clear message.
export function transformBigNumbers(obj: unknown): unknown { | ||
// Handle null/undefined | ||
if (obj === null || obj === undefined) { | ||
return obj; | ||
} | ||
|
||
// Handle BigNumber objects | ||
if (isBigNumberObject(obj)) { | ||
return bigNumberToStringifiedBigInt(obj); | ||
} | ||
|
||
// Handle arrays | ||
if (Array.isArray(obj)) { | ||
return obj.map(transformBigNumbers); | ||
} | ||
|
||
// Handle objects | ||
if (typeof obj === "object") { | ||
const result: Record<string, unknown> = {}; | ||
for (const [key, value] of Object.entries(obj)) { | ||
result[key] = transformBigNumbers(value); | ||
} | ||
return result; | ||
} | ||
|
||
// Handle primitives (string, number, boolean, etc.) | ||
return obj; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add protection against circular references.
The recursive function could cause stack overflow with circular references. Consider adding a WeakSet to track visited objects.
-export function transformBigNumbers(obj: unknown): unknown {
+export function transformBigNumbers(obj: unknown, visited = new WeakSet()): unknown {
// Handle null/undefined
if (obj === null || obj === undefined) {
return obj;
}
+ // Handle circular references
+ if (typeof obj === "object" && visited.has(obj as object)) {
+ return obj;
+ }
+
// Handle BigNumber objects
if (isBigNumberObject(obj)) {
return bigNumberToStringifiedBigInt(obj);
}
// Handle arrays
if (Array.isArray(obj)) {
+ visited.add(obj);
- return obj.map(transformBigNumbers);
+ return obj.map(item => transformBigNumbers(item, visited));
}
// Handle objects
if (typeof obj === "object") {
+ visited.add(obj);
const result: Record<string, unknown> = {};
for (const [key, value] of Object.entries(obj)) {
- result[key] = transformBigNumbers(value);
+ result[key] = transformBigNumbers(value, visited);
}
return result;
}
// Handle primitives (string, number, boolean, etc.)
return obj;
}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
export function transformBigNumbers(obj: unknown): unknown { | |
// Handle null/undefined | |
if (obj === null || obj === undefined) { | |
return obj; | |
} | |
// Handle BigNumber objects | |
if (isBigNumberObject(obj)) { | |
return bigNumberToStringifiedBigInt(obj); | |
} | |
// Handle arrays | |
if (Array.isArray(obj)) { | |
return obj.map(transformBigNumbers); | |
} | |
// Handle objects | |
if (typeof obj === "object") { | |
const result: Record<string, unknown> = {}; | |
for (const [key, value] of Object.entries(obj)) { | |
result[key] = transformBigNumbers(value); | |
} | |
return result; | |
} | |
// Handle primitives (string, number, boolean, etc.) | |
return obj; | |
} | |
export function transformBigNumbers( | |
obj: unknown, | |
visited = new WeakSet<object>() | |
): unknown { | |
// Handle null/undefined | |
if (obj === null || obj === undefined) { | |
return obj; | |
} | |
// Handle circular references | |
if (typeof obj === "object" && visited.has(obj as object)) { | |
return obj; | |
} | |
// Handle BigNumber objects | |
if (isBigNumberObject(obj)) { | |
return bigNumberToStringifiedBigInt(obj); | |
} | |
// Handle arrays | |
if (Array.isArray(obj)) { | |
visited.add(obj); | |
return obj.map(item => transformBigNumbers(item, visited)); | |
} | |
// Handle objects | |
if (typeof obj === "object") { | |
visited.add(obj); | |
const result: Record<string, unknown> = {}; | |
for (const [key, value] of Object.entries(obj)) { | |
result[key] = transformBigNumbers(value, visited); | |
} | |
return result; | |
} | |
// Handle primitives (string, number, boolean, etc.) | |
return obj; | |
} |
🤖 Prompt for AI Agents
In src/shared/utils/bignumber.ts between lines 39 and 66, the
transformBigNumbers function lacks protection against circular references, which
can cause infinite recursion and stack overflow. Fix this by adding a WeakSet
parameter to track visited objects during recursion. Before processing an object
or array, check if it has already been visited; if so, return it directly to
avoid reprocessing. Pass this WeakSet through recursive calls to maintain state
across the traversal.
Fixes BLD-37
Summary by CodeRabbit
New Features
Bug Fixes