Skip to content
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

chore: release v4.5.6 #589

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# @biconomy/account

## 4.5.7

### Patch Changes

- bundlerUrl fix

## 4.6.4

### Patch Changes

- shorten default pollInterval

## 4.6.3

### Patch Changes

- fix nextjs logs

## 4.6.2

### Patch Changes
Expand All @@ -10,8 +28,6 @@

### Patch Changes

- Taiko testnet fix

## 4.5.5

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"sideEffects": false,
"name": "@biconomy/account",
"author": "Biconomy",
"version": "4.6.2",
"version": "4.5.7",
"description": "SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.",
"keywords": [
"erc-7579",
Expand Down
17 changes: 1 addition & 16 deletions src/account/utils/Helpers.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1 @@
const VARS_T0_CHECK = [
"BICONOMY_SDK_DEBUG",
"REACT_APP_BICONOMY_SDK_DEBUG",
"NEXT_PUBLIC_BICONOMY_SDK_DEBUG"
]

export const isDebugging = (): boolean => {
try {
// @ts-ignore
return VARS_T0_CHECK.some(
(key) => process?.env?.[key]?.toString() === "true"
)
} catch (e) {
return false
}
}
export const isDebugging = () => !!process.env.NEXT_PUBLIC_BICONOMY_SDK_DEBUG || !!process.env.REACT_APP_BICONOMY_SDK_DEBUG || !!process.env.BICONOMY_SDK_DEBUG
15 changes: 6 additions & 9 deletions src/bundler/Bundler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type {
} from "./utils/Types.js"
import { extractChainIdFromBundlerUrl } from "./utils/Utils.js"

const POLL_INTERVAL = 2000;
/**
* This class implements IBundler interface.
* Implementation sends UserOperation to a bundler URL as per ERC4337 standard.
Expand Down Expand Up @@ -182,7 +183,7 @@ export class Bundler implements IBundler {
let totalDuration = 0

return new Promise<UserOpReceipt>((resolve, reject) => {
const intervalValue = this.UserOpReceiptIntervals[chainId] || 5000 // default 5 seconds
const intervalValue = this.UserOpReceiptIntervals[chainId] || POLL_INTERVAL
const intervalId = setInterval(async () => {
try {
const userOpResponse = await this.getUserOpReceipt(
Expand Down Expand Up @@ -215,10 +216,8 @@ export class Bundler implements IBundler {
clearInterval(intervalId)
reject(
new Error(
`Exceeded maximum duration (${
maxDuration / 1000
} sec) waiting to get receipt for userOpHash ${
sendUserOperationResponse.result
`Exceeded maximum duration (${maxDuration / 1000
} sec) waiting to get receipt for userOpHash ${sendUserOperationResponse.result
}. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler`
)
)
Expand Down Expand Up @@ -255,10 +254,8 @@ export class Bundler implements IBundler {
clearInterval(intervalId)
reject(
new Error(
`Exceeded maximum duration (${
maxDuration / 1000
} sec) waiting to get receipt for userOpHash ${
sendUserOperationResponse.result
`Exceeded maximum duration (${maxDuration / 1000
} sec) waiting to get receipt for userOpHash ${sendUserOperationResponse.result
}. Try getting the receipt manually using eth_getUserOperationReceipt rpc method on bundler`
)
)
Expand Down
63 changes: 45 additions & 18 deletions src/bundler/utils/Utils.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,50 @@
export const extractChainIdFromBundlerUrl = (url: string): number => {
/**
* Extracts the chain ID from a given URL.
*
* @param url - The URL to extract the chain ID from.
* @returns The extracted chain ID as a number.
* @throws {Error} If the chain ID is not found in the URL or is invalid.
*
* @example
* // Returns 80001
* extractChainIdFromUrl("https://example.com/api/v2/80001/rpc")
*/
export const extractChainIdFromUrl = (url: string): number => {
try {
const regex = /\/api\/v2\/(\d+)\/[a-zA-Z0-9.-]+$/
// biome-ignore lint/style/noNonNullAssertion: <explanation>
const match = regex.exec(url)!
return Number.parseInt(match[1])
} catch (error) {
throw new Error("Invalid chain id")
}
}

export const extractChainIdFromPaymasterUrl = (url: string): number => {
try {
const regex = /\/api\/v\d+\/(\d+)\//
const match = regex.exec(url)
const regex = /\/(\d+)\//;
const match = regex.exec(new URL(url).pathname);
if (!match) {
throw new Error("Invalid URL format")
throw new Error("Chain ID not found in URL");
}
return Number.parseInt(match[1])
const chainId = Number.parseInt(match[1], 10);
if (Number.isNaN(chainId)) {
throw new Error("Invalid chain ID");
}
return chainId;
} catch (error) {
throw new Error("Invalid chain id")
if (error instanceof Error) {
throw new Error(`Invalid chain id: ${error.message}`);
}
throw new Error("Invalid chain id");
}
}
};

/**
* Extracts the chain ID from a bundler URL.
*
* @param url - The bundler URL to extract the chain ID from.
* @returns The extracted chain ID as a number.
* @throws {Error} If the chain ID is not found in the URL or is invalid.
*/
export const extractChainIdFromBundlerUrl = (url: string): number =>
extractChainIdFromUrl(url);

/**
* Extracts the chain ID from a paymaster URL.
*
* @param url - The paymaster URL to extract the chain ID from.
* @returns The extracted chain ID as a number.
* @throws {Error} If the chain ID is not found in the URL or is invalid.
*/
export const extractChainIdFromPaymasterUrl = (url: string): number =>
extractChainIdFromUrl(url);
37 changes: 31 additions & 6 deletions tests/bundler/read.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import {
type BiconomySmartAccountV2Config,
compareChainIds,
createSmartAccountClient,
getCustomChain
} from "../../src/account"
import { createBundler } from "../../src/bundler"
import { createBundler, extractChainIdFromUrl } from "../../src/bundler"
import { getBundlerUrl, getConfig } from "../utils"

describe("Bundler:Read", () => {
Expand Down Expand Up @@ -51,11 +50,11 @@ describe("Bundler:Read", () => {
})
)
)
;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all(
[smartAccount, smartAccountTwo].map((account) =>
account.getAccountAddress()
;[smartAccountAddress, smartAccountAddressTwo] = await Promise.all(
[smartAccount, smartAccountTwo].map((account) =>
account.getAccountAddress()
)
)
)
})

test.concurrent(
Expand Down Expand Up @@ -200,4 +199,30 @@ describe("Bundler:Read", () => {
await expect(createAccount).rejects.toThrow()
}
)

test.concurrent('extracts chain ID from various URL structures', () => {
const testCases = [
{ url: "https://example.com/api/v2/1234/endpoint", expected: 1234 },
{ url: "https://api.example.com/v1/5678/resource", expected: 5678 },
{ url: "http://localhost:3000/api/9876/action", expected: 9876 },
{ url: "https://example.com/1234/api/v2/endpoint", expected: 1234 },
{ url: "https://example.com/network/5678/resource/action", expected: 5678 },
{ url: "https://api.example.com/prefix/9876/suffix", expected: 9876 },
{ url: "https://example.com/api/v2/1234/5678/endpoint", expected: 1234 },
{ url: "https://example.com/api/v2/endpoint/1234/", expected: 1234 },
{ url: "https://example.com/api/v2/1234/endpoint?param=value", expected: 1234 },
{ url: "https://example.com/api/v2/1234/endpoint#section", expected: 1234 },
{ url: "https://subdomain.example.com/api/1234/endpoint", expected: 1234 },
{ url: "http://192.168.1.1/api/1234/endpoint", expected: 1234 },
{ url: "https://user:[email protected]/api/1234/endpoint", expected: 1234 },
{ url: "https://example.com/1234/", expected: 1234 },
{ url: "https://api.example.com/v1/chain/5678/details", expected: 5678 },
{ url: "https://paymaster.biconomy.io/api/v1/80001/-RObQRX9ei.fc6918eb-c582-4417-9d5a-0507b17cfe71", expected: 80001 },
{ url: "https://bundler.biconomy.io/api/v2/80002/nJPK7B3ru.dd7f7861-190d-41bd-af80-6877f74b8f44", expected: 80002 },
];

for (const { url, expected } of testCases) {
expect(extractChainIdFromUrl(url)).toBe(expected);
}
})
})
Loading