thirdweb 5.102.4-nightly-283dc289fca1ad16a9296e610d293b73a7123709-20250602000433 → 5.102.4-nightly-de297e4c9787982f0d66d3898f32a45768a68bc9-20250603000531
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/analytics/track/helpers.js +41 -0
- package/dist/cjs/analytics/track/helpers.js.map +1 -0
- package/dist/cjs/analytics/track/transaction.js +25 -0
- package/dist/cjs/analytics/track/transaction.js.map +1 -1
- package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js +13 -0
- package/dist/cjs/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/cjs/transaction/actions/estimate-gas.js +2 -0
- package/dist/cjs/transaction/actions/estimate-gas.js.map +1 -1
- package/dist/cjs/transaction/actions/simulate.js +1 -0
- package/dist/cjs/transaction/actions/simulate.js.map +1 -1
- package/dist/cjs/transaction/extract-error.js +13 -1
- package/dist/cjs/transaction/extract-error.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/wallets/injected/index.js +35 -17
- package/dist/cjs/wallets/injected/index.js.map +1 -1
- package/dist/cjs/wallets/smart/index.js +16 -0
- package/dist/cjs/wallets/smart/index.js.map +1 -1
- package/dist/esm/analytics/track/helpers.js +37 -0
- package/dist/esm/analytics/track/helpers.js.map +1 -0
- package/dist/esm/analytics/track/transaction.js +24 -0
- package/dist/esm/analytics/track/transaction.js.map +1 -1
- package/dist/esm/react/core/hooks/transaction/useSendTransaction.js +13 -0
- package/dist/esm/react/core/hooks/transaction/useSendTransaction.js.map +1 -1
- package/dist/esm/transaction/actions/estimate-gas.js +2 -0
- package/dist/esm/transaction/actions/estimate-gas.js.map +1 -1
- package/dist/esm/transaction/actions/simulate.js +1 -0
- package/dist/esm/transaction/actions/simulate.js.map +1 -1
- package/dist/esm/transaction/extract-error.js +13 -1
- package/dist/esm/transaction/extract-error.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/wallets/injected/index.js +35 -17
- package/dist/esm/wallets/injected/index.js.map +1 -1
- package/dist/esm/wallets/smart/index.js +16 -0
- package/dist/esm/wallets/smart/index.js.map +1 -1
- package/dist/types/analytics/track/helpers.d.ts +12 -0
- package/dist/types/analytics/track/helpers.d.ts.map +1 -0
- package/dist/types/analytics/track/transaction.d.ts +15 -0
- package/dist/types/analytics/track/transaction.d.ts.map +1 -1
- package/dist/types/react/core/hooks/transaction/useSendTransaction.d.ts.map +1 -1
- package/dist/types/transaction/actions/estimate-gas.d.ts.map +1 -1
- package/dist/types/transaction/actions/simulate.d.ts.map +1 -1
- package/dist/types/transaction/extract-error.d.ts +1 -0
- package/dist/types/transaction/extract-error.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/wallets/injected/index.d.ts.map +1 -1
- package/dist/types/wallets/smart/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/analytics/track/helpers.test.ts +109 -0
- package/src/analytics/track/helpers.ts +49 -0
- package/src/analytics/track/transaction.test.ts +110 -1
- package/src/analytics/track/transaction.ts +37 -0
- package/src/react/core/hooks/transaction/useSendTransaction.ts +14 -0
- package/src/transaction/actions/estimate-gas.ts +2 -0
- package/src/transaction/actions/simulate.ts +1 -0
- package/src/transaction/extract-error.ts +16 -1
- package/src/version.ts +1 -1
- package/src/wallets/injected/index.ts +36 -18
- package/src/wallets/smart/index.ts +16 -0
@@ -2,7 +2,10 @@ import { http, HttpResponse } from "msw";
|
|
2
2
|
import { setupServer } from "msw/node";
|
3
3
|
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
4
4
|
import type { ThirdwebClient } from "../../client/client.js";
|
5
|
-
import {
|
5
|
+
import {
|
6
|
+
trackInsufficientFundsError,
|
7
|
+
trackTransaction,
|
8
|
+
} from "./transaction.js";
|
6
9
|
|
7
10
|
const server = setupServer(
|
8
11
|
http.post("https://c.thirdweb.com/event", () => {
|
@@ -127,4 +130,110 @@ describe("transaction tracking", () => {
|
|
127
130
|
"test-partner-id",
|
128
131
|
);
|
129
132
|
});
|
133
|
+
|
134
|
+
it("should track insufficient funds error with correct data", async () => {
|
135
|
+
const mockClient: ThirdwebClient = {
|
136
|
+
clientId: "test-client-id",
|
137
|
+
secretKey: undefined,
|
138
|
+
};
|
139
|
+
|
140
|
+
let requestBody: unknown;
|
141
|
+
server.use(
|
142
|
+
http.post("https://c.thirdweb.com/event", async (handler) => {
|
143
|
+
requestBody = await handler.request.json();
|
144
|
+
return HttpResponse.json({});
|
145
|
+
}),
|
146
|
+
);
|
147
|
+
|
148
|
+
const mockError = new Error("Insufficient funds for gas * price + value");
|
149
|
+
|
150
|
+
await trackInsufficientFundsError({
|
151
|
+
client: mockClient,
|
152
|
+
error: mockError,
|
153
|
+
walletAddress: "0x1234567890123456789012345678901234567890",
|
154
|
+
chainId: 1,
|
155
|
+
contractAddress: "0xcontract",
|
156
|
+
transactionValue: 1000000000000000000n,
|
157
|
+
});
|
158
|
+
|
159
|
+
expect(requestBody).toEqual({
|
160
|
+
source: "sdk",
|
161
|
+
action: "transaction:insufficient_funds",
|
162
|
+
clientId: "test-client-id",
|
163
|
+
chainId: 1,
|
164
|
+
walletAddress: "0x1234567890123456789012345678901234567890",
|
165
|
+
contractAddress: "0xcontract",
|
166
|
+
transactionValue: "1000000000000000000",
|
167
|
+
requiredAmount: undefined,
|
168
|
+
userBalance: undefined,
|
169
|
+
errorMessage: "Insufficient funds for gas * price + value",
|
170
|
+
errorCode: undefined,
|
171
|
+
});
|
172
|
+
});
|
173
|
+
|
174
|
+
it("should not throw an error if insufficient funds tracking request fails", async () => {
|
175
|
+
const mockClient: ThirdwebClient = {
|
176
|
+
clientId: "test-client-id",
|
177
|
+
secretKey: undefined,
|
178
|
+
};
|
179
|
+
|
180
|
+
server.use(
|
181
|
+
http.post("https://c.thirdweb.com/event", () => {
|
182
|
+
return HttpResponse.error();
|
183
|
+
}),
|
184
|
+
);
|
185
|
+
|
186
|
+
const mockError = new Error("insufficient funds");
|
187
|
+
|
188
|
+
expect(() =>
|
189
|
+
trackInsufficientFundsError({
|
190
|
+
client: mockClient,
|
191
|
+
error: mockError,
|
192
|
+
walletAddress: "0x1234567890123456789012345678901234567890",
|
193
|
+
chainId: 137,
|
194
|
+
}),
|
195
|
+
).not.toThrowError();
|
196
|
+
|
197
|
+
// Wait for the asynchronous POST request to complete
|
198
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
199
|
+
});
|
200
|
+
|
201
|
+
it("should track insufficient funds error during transaction preparation", async () => {
|
202
|
+
const mockClient: ThirdwebClient = {
|
203
|
+
clientId: "test-client-id",
|
204
|
+
secretKey: undefined,
|
205
|
+
};
|
206
|
+
|
207
|
+
let requestBody: unknown;
|
208
|
+
server.use(
|
209
|
+
http.post("https://c.thirdweb.com/event", async (handler) => {
|
210
|
+
requestBody = await handler.request.json();
|
211
|
+
return HttpResponse.json({});
|
212
|
+
}),
|
213
|
+
);
|
214
|
+
|
215
|
+
const mockError = new Error("insufficient funds for gas");
|
216
|
+
|
217
|
+
await trackInsufficientFundsError({
|
218
|
+
client: mockClient,
|
219
|
+
error: mockError,
|
220
|
+
walletAddress: "0xabcdef1234567890abcdef1234567890abcdef12",
|
221
|
+
chainId: 42,
|
222
|
+
contractAddress: "0x0987654321098765432109876543210987654321",
|
223
|
+
});
|
224
|
+
|
225
|
+
expect(requestBody).toEqual({
|
226
|
+
source: "sdk",
|
227
|
+
action: "transaction:insufficient_funds",
|
228
|
+
clientId: "test-client-id",
|
229
|
+
chainId: 42,
|
230
|
+
walletAddress: "0xabcdef1234567890abcdef1234567890abcdef12",
|
231
|
+
contractAddress: "0x0987654321098765432109876543210987654321",
|
232
|
+
transactionValue: undefined,
|
233
|
+
requiredAmount: undefined,
|
234
|
+
userBalance: undefined,
|
235
|
+
errorMessage: "insufficient funds for gas",
|
236
|
+
errorCode: undefined,
|
237
|
+
});
|
238
|
+
});
|
130
239
|
});
|
@@ -2,6 +2,7 @@ import type { ThirdwebClient } from "../../client/client.js";
|
|
2
2
|
import { stringify } from "../../utils/json.js";
|
3
3
|
import type { Ecosystem } from "../../wallets/in-app/core/wallet/types.js";
|
4
4
|
import type { WalletId } from "../../wallets/wallet-types.js";
|
5
|
+
import { getErrorDetails } from "./helpers.js";
|
5
6
|
import { track } from "./index.js";
|
6
7
|
|
7
8
|
type TransactionEvent = {
|
@@ -55,3 +56,39 @@ function trackTransactionEvent(
|
|
55
56
|
},
|
56
57
|
});
|
57
58
|
}
|
59
|
+
|
60
|
+
/**
|
61
|
+
* @internal
|
62
|
+
*/
|
63
|
+
export async function trackInsufficientFundsError(args: {
|
64
|
+
client: ThirdwebClient;
|
65
|
+
ecosystem?: Ecosystem;
|
66
|
+
error: Error | unknown;
|
67
|
+
walletAddress?: string;
|
68
|
+
chainId?: number;
|
69
|
+
contractAddress?: string;
|
70
|
+
functionName?: string;
|
71
|
+
transactionValue?: bigint;
|
72
|
+
requiredAmount?: bigint;
|
73
|
+
userBalance?: bigint;
|
74
|
+
}) {
|
75
|
+
const errorDetails = getErrorDetails(args.error);
|
76
|
+
|
77
|
+
return track({
|
78
|
+
client: args.client,
|
79
|
+
ecosystem: args.ecosystem,
|
80
|
+
data: {
|
81
|
+
action: "transaction:insufficient_funds",
|
82
|
+
clientId: args.client.clientId,
|
83
|
+
chainId: args.chainId,
|
84
|
+
walletAddress: args.walletAddress,
|
85
|
+
contractAddress: args.contractAddress,
|
86
|
+
functionName: args.functionName,
|
87
|
+
transactionValue: args.transactionValue?.toString(),
|
88
|
+
requiredAmount: args.requiredAmount?.toString(),
|
89
|
+
userBalance: args.userBalance?.toString(),
|
90
|
+
errorMessage: errorDetails.message,
|
91
|
+
errorCode: errorDetails.code ? stringify(errorDetails.code) : undefined,
|
92
|
+
},
|
93
|
+
});
|
94
|
+
}
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import { type UseMutationResult, useMutation } from "@tanstack/react-query";
|
2
|
+
import { isInsufficientFundsError } from "../../../../analytics/track/helpers.js";
|
2
3
|
import { trackPayEvent } from "../../../../analytics/track/pay.js";
|
4
|
+
import { trackInsufficientFundsError } from "../../../../analytics/track/transaction.js";
|
3
5
|
import * as Bridge from "../../../../bridge/index.js";
|
4
6
|
import type { Chain } from "../../../../chains/types.js";
|
5
7
|
import type { BuyWithCryptoStatus } from "../../../../pay/buyWithCrypto/getStatus.js";
|
@@ -174,6 +176,18 @@ export function useSendTransactionCore(args: {
|
|
174
176
|
|
175
177
|
resolve(res);
|
176
178
|
} catch (e) {
|
179
|
+
// Track insufficient funds errors specifically
|
180
|
+
if (isInsufficientFundsError(e)) {
|
181
|
+
trackInsufficientFundsError({
|
182
|
+
client: tx.client,
|
183
|
+
error: e,
|
184
|
+
walletAddress: account.address,
|
185
|
+
chainId: tx.chain.id,
|
186
|
+
contractAddress: await resolvePromisedValue(tx.to ?? undefined),
|
187
|
+
transactionValue: await resolvePromisedValue(tx.value),
|
188
|
+
});
|
189
|
+
}
|
190
|
+
|
177
191
|
reject(e);
|
178
192
|
}
|
179
193
|
};
|
@@ -94,6 +94,7 @@ export async function estimateGas(
|
|
94
94
|
throw await extractError({
|
95
95
|
error,
|
96
96
|
contract: options.transaction.__contract,
|
97
|
+
fromAddress,
|
97
98
|
});
|
98
99
|
}
|
99
100
|
}
|
@@ -150,6 +151,7 @@ export async function estimateGas(
|
|
150
151
|
throw await extractError({
|
151
152
|
error,
|
152
153
|
contract: options.transaction.__contract,
|
154
|
+
fromAddress,
|
153
155
|
});
|
154
156
|
}
|
155
157
|
})();
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import type { Abi } from "abitype";
|
2
2
|
import { type Hex, decodeErrorResult, stringify } from "viem";
|
3
|
+
import { isInsufficientFundsError } from "../analytics/track/helpers.js";
|
4
|
+
import { trackInsufficientFundsError } from "../analytics/track/transaction.js";
|
3
5
|
import { resolveContractAbi } from "../contract/actions/resolve-abi.js";
|
4
6
|
import type { ThirdwebContract } from "../contract/contract.js";
|
5
7
|
import { isHex } from "../utils/encoding/hex.js";
|
@@ -11,8 +13,21 @@ import { IS_DEV } from "../utils/process.js";
|
|
11
13
|
export async function extractError<abi extends Abi>(args: {
|
12
14
|
error: unknown;
|
13
15
|
contract?: ThirdwebContract<abi>;
|
16
|
+
fromAddress?: string;
|
14
17
|
}) {
|
15
|
-
const { error, contract } = args;
|
18
|
+
const { error, contract, fromAddress } = args;
|
19
|
+
|
20
|
+
// Track insufficient funds errors during transaction preparation
|
21
|
+
if (isInsufficientFundsError(error) && contract) {
|
22
|
+
trackInsufficientFundsError({
|
23
|
+
client: contract.client,
|
24
|
+
error,
|
25
|
+
walletAddress: fromAddress,
|
26
|
+
chainId: contract.chain?.id,
|
27
|
+
contractAddress: contract.address,
|
28
|
+
});
|
29
|
+
}
|
30
|
+
|
16
31
|
const result = await extractErrorResult({ error, contract });
|
17
32
|
if (result) {
|
18
33
|
return new TransactionError(result, contract);
|
package/src/version.ts
CHANGED
@@ -1 +1 @@
|
|
1
|
-
export const version = "5.102.4-nightly-
|
1
|
+
export const version = "5.102.4-nightly-de297e4c9787982f0d66d3898f32a45768a68bc9-20250603000531";
|
@@ -5,7 +5,9 @@ import {
|
|
5
5
|
serializeTypedData,
|
6
6
|
validateTypedData,
|
7
7
|
} from "viem";
|
8
|
+
import { isInsufficientFundsError } from "../../analytics/track/helpers.js";
|
8
9
|
import { trackTransaction } from "../../analytics/track/transaction.js";
|
10
|
+
import { trackInsufficientFundsError } from "../../analytics/track/transaction.js";
|
9
11
|
import type { Chain } from "../../chains/types.js";
|
10
12
|
import { getCachedChain, getChainMetadata } from "../../chains/utils.js";
|
11
13
|
import type { ThirdwebClient } from "../../client/client.js";
|
@@ -200,25 +202,41 @@ function createAccount({
|
|
200
202
|
},
|
201
203
|
];
|
202
204
|
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
205
|
+
try {
|
206
|
+
const transactionHash = (await provider.request({
|
207
|
+
method: "eth_sendTransaction",
|
208
|
+
// @ts-expect-error - overriding types here
|
209
|
+
params,
|
210
|
+
})) as Hex;
|
211
|
+
|
212
|
+
trackTransaction({
|
213
|
+
client,
|
214
|
+
chainId: tx.chainId,
|
215
|
+
walletAddress: getAddress(address),
|
216
|
+
walletType: id,
|
217
|
+
transactionHash,
|
218
|
+
contractAddress: tx.to ?? undefined,
|
219
|
+
gasPrice: tx.gasPrice,
|
220
|
+
});
|
221
|
+
|
222
|
+
return {
|
223
|
+
transactionHash,
|
224
|
+
};
|
225
|
+
} catch (error) {
|
226
|
+
// Track insufficient funds errors
|
227
|
+
if (isInsufficientFundsError(error)) {
|
228
|
+
trackInsufficientFundsError({
|
229
|
+
client,
|
230
|
+
error,
|
231
|
+
walletAddress: getAddress(address),
|
232
|
+
chainId: tx.chainId,
|
233
|
+
contractAddress: tx.to || undefined,
|
234
|
+
transactionValue: tx.value,
|
235
|
+
});
|
236
|
+
}
|
218
237
|
|
219
|
-
|
220
|
-
|
221
|
-
};
|
238
|
+
throw error;
|
239
|
+
}
|
222
240
|
},
|
223
241
|
async signMessage({ message }) {
|
224
242
|
if (!account.address) {
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import type * as ox__TypedData from "ox/TypedData";
|
2
|
+
import { isInsufficientFundsError } from "../../analytics/track/helpers.js";
|
2
3
|
import { trackTransaction } from "../../analytics/track/transaction.js";
|
4
|
+
import { trackInsufficientFundsError } from "../../analytics/track/transaction.js";
|
3
5
|
import type { Chain } from "../../chains/types.js";
|
4
6
|
import { getCachedChain } from "../../chains/utils.js";
|
5
7
|
import type { ThirdwebClient } from "../../client/client.js";
|
@@ -559,6 +561,20 @@ async function _sendUserOp(args: {
|
|
559
561
|
chain: options.chain,
|
560
562
|
transactionHash: receipt.transactionHash,
|
561
563
|
};
|
564
|
+
} catch (error) {
|
565
|
+
// Track insufficient funds errors
|
566
|
+
if (isInsufficientFundsError(error)) {
|
567
|
+
trackInsufficientFundsError({
|
568
|
+
client: options.client,
|
569
|
+
error,
|
570
|
+
walletAddress: options.accountContract.address,
|
571
|
+
chainId: options.chain.id,
|
572
|
+
contractAddress: await resolvePromisedValue(executeTx.to ?? undefined),
|
573
|
+
transactionValue: await resolvePromisedValue(executeTx.value),
|
574
|
+
});
|
575
|
+
}
|
576
|
+
|
577
|
+
throw error;
|
562
578
|
} finally {
|
563
579
|
// reset the isDeploying flag after every transaction or error
|
564
580
|
clearAccountDeploying(options.accountContract);
|