thirdweb 5.94.2 → 5.95.0-nightly-64bd603301b3067b6a69a29f66a28dee7ffa38f5-20250416000349
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/chains/utils.js +41 -0
- package/dist/cjs/chains/utils.js.map +1 -1
- package/dist/cjs/event/actions/get-events.js +65 -11
- package/dist/cjs/event/actions/get-events.js.map +1 -1
- package/dist/cjs/exports/insight.js +5 -0
- package/dist/cjs/exports/insight.js.map +1 -0
- package/dist/cjs/exports/thirdweb.js +6 -2
- package/dist/cjs/exports/thirdweb.js.map +1 -1
- package/dist/cjs/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js +104 -0
- package/dist/cjs/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js.map +1 -0
- package/dist/cjs/extensions/thirdweb/write/publish.js +9 -4
- package/dist/cjs/extensions/thirdweb/write/publish.js.map +1 -1
- package/dist/cjs/insight/get-events.js +54 -0
- package/dist/cjs/insight/get-events.js.map +1 -0
- package/dist/cjs/insight/get-nfts.js +45 -0
- package/dist/cjs/insight/get-nfts.js.map +1 -0
- package/dist/cjs/insight/get-tokens.js +46 -0
- package/dist/cjs/insight/get-tokens.js.map +1 -0
- package/dist/cjs/insight/get-transactions.js +45 -0
- package/dist/cjs/insight/get-transactions.js.map +1 -0
- package/dist/cjs/insight/index.js +12 -0
- package/dist/cjs/insight/index.js.map +1 -0
- package/dist/cjs/pay/buyWithCrypto/getHistory.js +2 -2
- package/dist/cjs/pay/buyWithCrypto/getHistory.js.map +1 -1
- package/dist/cjs/pay/buyWithCrypto/getStatus.js +2 -2
- package/dist/cjs/pay/buyWithCrypto/getStatus.js.map +1 -1
- package/dist/cjs/pay/buyWithFiat/getHistory.js +2 -2
- package/dist/cjs/pay/buyWithFiat/getHistory.js.map +1 -1
- package/dist/cjs/pay/buyWithFiat/getStatus.js +2 -2
- package/dist/cjs/pay/buyWithFiat/getStatus.js.map +1 -1
- package/dist/cjs/pay/getBuyHistory.js +2 -2
- package/dist/cjs/pay/getBuyHistory.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js +4 -14
- package/dist/cjs/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +6 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +2 -2
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +3 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/SendFunds.js +3 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/SendFunds.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewAssets.js +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewAssets.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js +74 -32
- package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -1
- package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js +46 -6
- package/dist/cjs/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -1
- package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js +4 -1
- package/dist/cjs/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
- package/dist/cjs/rpc/fetch-rpc.js +4 -4
- package/dist/cjs/rpc/fetch-rpc.js.map +1 -1
- package/dist/cjs/transaction/actions/gasless/providers/biconomy.js +0 -1
- package/dist/cjs/transaction/actions/gasless/providers/biconomy.js.map +1 -1
- package/dist/cjs/transaction/actions/gasless/providers/openzeppelin.js +0 -1
- package/dist/cjs/transaction/actions/gasless/providers/openzeppelin.js.map +1 -1
- package/dist/cjs/transaction/transaction-store.js +11 -10
- package/dist/cjs/transaction/transaction-store.js.map +1 -1
- package/dist/cjs/utils/fetch.js +5 -4
- package/dist/cjs/utils/fetch.js.map +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/cjs/version.js.map +1 -1
- package/dist/esm/chains/utils.js +40 -0
- package/dist/esm/chains/utils.js.map +1 -1
- package/dist/esm/event/actions/get-events.js +62 -8
- package/dist/esm/event/actions/get-events.js.map +1 -1
- package/dist/esm/exports/insight.js +2 -0
- package/dist/esm/exports/insight.js.map +1 -0
- package/dist/esm/exports/thirdweb.js +4 -0
- package/dist/esm/exports/thirdweb.js.map +1 -1
- package/dist/esm/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js +98 -0
- package/dist/esm/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js.map +1 -0
- package/dist/esm/extensions/thirdweb/write/publish.js +9 -4
- package/dist/esm/extensions/thirdweb/write/publish.js.map +1 -1
- package/dist/esm/insight/get-events.js +51 -0
- package/dist/esm/insight/get-events.js.map +1 -0
- package/dist/esm/insight/get-nfts.js +42 -0
- package/dist/esm/insight/get-nfts.js.map +1 -0
- package/dist/esm/insight/get-tokens.js +43 -0
- package/dist/esm/insight/get-tokens.js.map +1 -0
- package/dist/esm/insight/get-transactions.js +42 -0
- package/dist/esm/insight/get-transactions.js.map +1 -0
- package/dist/esm/insight/index.js +5 -0
- package/dist/esm/insight/index.js.map +1 -0
- package/dist/esm/pay/buyWithCrypto/getHistory.js +2 -2
- package/dist/esm/pay/buyWithCrypto/getHistory.js.map +1 -1
- package/dist/esm/pay/buyWithCrypto/getStatus.js +2 -2
- package/dist/esm/pay/buyWithCrypto/getStatus.js.map +1 -1
- package/dist/esm/pay/buyWithFiat/getHistory.js +2 -2
- package/dist/esm/pay/buyWithFiat/getHistory.js.map +1 -1
- package/dist/esm/pay/buyWithFiat/getStatus.js +2 -2
- package/dist/esm/pay/buyWithFiat/getStatus.js.map +1 -1
- package/dist/esm/pay/getBuyHistory.js +2 -2
- package/dist/esm/pay/getBuyHistory.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/Details.js +4 -14
- package/dist/esm/react/web/ui/ConnectWallet/Details.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js +6 -2
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js +2 -2
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js +3 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/SendFunds.js +3 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/SendFunds.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/ViewAssets.js +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/ViewAssets.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js +75 -33
- package/dist/esm/react/web/ui/ConnectWallet/screens/ViewNFTs.js.map +1 -1
- package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js +46 -6
- package/dist/esm/react/web/ui/ConnectWallet/screens/ViewTokens.js.map +1 -1
- package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js +4 -1
- package/dist/esm/react/web/ui/MediaRenderer/useResolvedMediaType.js.map +1 -1
- package/dist/esm/rpc/fetch-rpc.js +4 -4
- package/dist/esm/rpc/fetch-rpc.js.map +1 -1
- package/dist/esm/transaction/actions/gasless/providers/biconomy.js +0 -1
- package/dist/esm/transaction/actions/gasless/providers/biconomy.js.map +1 -1
- package/dist/esm/transaction/actions/gasless/providers/openzeppelin.js +0 -1
- package/dist/esm/transaction/actions/gasless/providers/openzeppelin.js.map +1 -1
- package/dist/esm/transaction/transaction-store.js +11 -10
- package/dist/esm/transaction/transaction-store.js.map +1 -1
- package/dist/esm/utils/fetch.js +5 -4
- package/dist/esm/utils/fetch.js.map +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/esm/version.js.map +1 -1
- package/dist/types/chains/types.d.ts +7 -0
- package/dist/types/chains/types.d.ts.map +1 -1
- package/dist/types/chains/utils.d.ts +15 -1
- package/dist/types/chains/utils.d.ts.map +1 -1
- package/dist/types/event/actions/get-events.d.ts +1 -6
- package/dist/types/event/actions/get-events.d.ts.map +1 -1
- package/dist/types/exports/insight.d.ts +2 -0
- package/dist/types/exports/insight.d.ts.map +1 -0
- package/dist/types/exports/thirdweb.d.ts +4 -0
- package/dist/types/exports/thirdweb.d.ts.map +1 -1
- package/dist/types/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.d.ts +64 -0
- package/dist/types/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.d.ts.map +1 -0
- package/dist/types/extensions/thirdweb/write/publish.d.ts.map +1 -1
- package/dist/types/insight/get-events.d.ts +31 -0
- package/dist/types/insight/get-events.d.ts.map +1 -0
- package/dist/types/insight/get-nfts.d.ts +25 -0
- package/dist/types/insight/get-nfts.d.ts.map +1 -0
- package/dist/types/insight/get-tokens.d.ts +25 -0
- package/dist/types/insight/get-tokens.d.ts.map +1 -0
- package/dist/types/insight/get-transactions.d.ts +25 -0
- package/dist/types/insight/get-transactions.d.ts.map +1 -0
- package/dist/types/insight/index.d.ts +5 -0
- package/dist/types/insight/index.d.ts.map +1 -0
- package/dist/types/pay/buyWithCrypto/getHistory.d.ts.map +1 -1
- package/dist/types/pay/buyWithCrypto/getStatus.d.ts.map +1 -1
- package/dist/types/pay/buyWithFiat/getHistory.d.ts.map +1 -1
- package/dist/types/pay/buyWithFiat/getStatus.d.ts.map +1 -1
- package/dist/types/pay/getBuyHistory.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/Details.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/SendFunds.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/ViewNFTs.d.ts.map +1 -1
- package/dist/types/react/web/ui/ConnectWallet/screens/ViewTokens.d.ts.map +1 -1
- package/dist/types/react/web/ui/MediaRenderer/useResolvedMediaType.d.ts +1 -1
- package/dist/types/react/web/ui/MediaRenderer/useResolvedMediaType.d.ts.map +1 -1
- package/dist/types/rpc/fetch-rpc.d.ts.map +1 -1
- package/dist/types/transaction/actions/gasless/providers/biconomy.d.ts.map +1 -1
- package/dist/types/transaction/actions/gasless/providers/openzeppelin.d.ts.map +1 -1
- package/dist/types/transaction/transaction-store.d.ts.map +1 -1
- package/dist/types/utils/fetch.d.ts +1 -1
- package/dist/types/utils/fetch.d.ts.map +1 -1
- package/dist/types/version.d.ts +1 -1
- package/dist/types/version.d.ts.map +1 -1
- package/package.json +8 -2
- package/src/chains/types.ts +8 -0
- package/src/chains/utils.ts +61 -0
- package/src/event/actions/get-events.test.ts +96 -0
- package/src/event/actions/get-events.ts +99 -12
- package/src/exports/insight.ts +1 -0
- package/src/exports/thirdweb.ts +5 -0
- package/src/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.ts +104 -0
- package/src/extensions/thirdweb/write/publish.ts +12 -4
- package/src/insight/get-events.ts +78 -0
- package/src/insight/get-nfts.ts +65 -0
- package/src/insight/get-tokens.ts +66 -0
- package/src/insight/get-transactions.ts +66 -0
- package/src/insight/index.ts +4 -0
- package/src/pay/buyWithCrypto/getHistory.ts +4 -2
- package/src/pay/buyWithCrypto/getStatus.ts +4 -2
- package/src/pay/buyWithFiat/getHistory.ts +4 -2
- package/src/pay/buyWithFiat/getStatus.ts +4 -2
- package/src/pay/getBuyHistory.ts +4 -2
- package/src/react/web/ui/ConnectWallet/Details.tsx +15 -33
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/ConfirmationScreen.tsx +10 -2
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TokenSelectorScreen.tsx +2 -2
- package/src/react/web/ui/ConnectWallet/screens/Buy/swap/TransferConfirmationScreen.tsx +5 -1
- package/src/react/web/ui/ConnectWallet/screens/SendFunds.tsx +5 -1
- package/src/react/web/ui/ConnectWallet/screens/ViewAssets.tsx +1 -1
- package/src/react/web/ui/ConnectWallet/screens/ViewNFTs.tsx +107 -55
- package/src/react/web/ui/ConnectWallet/screens/ViewTokens.tsx +94 -11
- package/src/react/web/ui/MediaRenderer/useResolvedMediaType.ts +4 -1
- package/src/rpc/fetch-rpc.ts +6 -4
- package/src/transaction/actions/gasless/providers/biconomy.ts +0 -1
- package/src/transaction/actions/gasless/providers/openzeppelin.ts +0 -1
- package/src/transaction/transaction-store.ts +11 -22
- package/src/utils/fetch.ts +6 -5
- package/src/version.ts +1 -1
package/src/chains/utils.ts
CHANGED
@@ -7,6 +7,7 @@ import type {
|
|
7
7
|
Chain,
|
8
8
|
ChainMetadata,
|
9
9
|
ChainOptions,
|
10
|
+
ChainService,
|
10
11
|
LegacyChain,
|
11
12
|
} from "./types.js";
|
12
13
|
|
@@ -321,6 +322,66 @@ export function getChainMetadata(chain: Chain): Promise<ChainMetadata> {
|
|
321
322
|
);
|
322
323
|
}
|
323
324
|
|
325
|
+
type FetchChainServiceResponse =
|
326
|
+
| {
|
327
|
+
data: {
|
328
|
+
services: ChainService[];
|
329
|
+
};
|
330
|
+
error?: never;
|
331
|
+
}
|
332
|
+
| {
|
333
|
+
data?: never;
|
334
|
+
error: unknown;
|
335
|
+
};
|
336
|
+
|
337
|
+
/**
|
338
|
+
* Retrieves a list of services available on a given chain
|
339
|
+
* @param chain - The chain object containing the chain ID.
|
340
|
+
* @returns A Promise that resolves to chain services.
|
341
|
+
* @throws If there is an error fetching the chain services.
|
342
|
+
* @example
|
343
|
+
* ```ts
|
344
|
+
* const chain = defineChain({ id: 1 });
|
345
|
+
* const chainServices = await getChainServices(chain);
|
346
|
+
* console.log(chainServices);
|
347
|
+
* ```
|
348
|
+
* @chain
|
349
|
+
*/
|
350
|
+
export function getChainServices(chain: Chain): Promise<ChainService[]> {
|
351
|
+
const chainId = chain.id;
|
352
|
+
return withCache(
|
353
|
+
async () => {
|
354
|
+
try {
|
355
|
+
const res = await fetch(
|
356
|
+
`https://api.thirdweb.com/v1/chains/${chainId}/services`,
|
357
|
+
);
|
358
|
+
if (!res.ok) {
|
359
|
+
res.body?.cancel();
|
360
|
+
throw new Error(`Failed to fetch services for chainId ${chainId}`);
|
361
|
+
}
|
362
|
+
|
363
|
+
const response = (await res.json()) as FetchChainServiceResponse;
|
364
|
+
if (response.error) {
|
365
|
+
throw new Error(`Failed to fetch services for chainId ${chainId}`);
|
366
|
+
}
|
367
|
+
if (!response.data) {
|
368
|
+
throw new Error(`Failed to fetch services for chainId ${chainId}`);
|
369
|
+
}
|
370
|
+
|
371
|
+
const services = response.data.services;
|
372
|
+
|
373
|
+
return services;
|
374
|
+
} catch {
|
375
|
+
throw new Error(`Failed to fetch services for chainId ${chainId}`);
|
376
|
+
}
|
377
|
+
},
|
378
|
+
{
|
379
|
+
cacheKey: `chain:${chainId}:services`,
|
380
|
+
cacheTime: 24 * 60 * 60 * 1000, // 1 day
|
381
|
+
},
|
382
|
+
);
|
383
|
+
}
|
384
|
+
|
324
385
|
/**
|
325
386
|
* Convert `ApiChain` to `Chain` object
|
326
387
|
* @internal
|
@@ -15,6 +15,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
15
15
|
const events = await getContractEvents({
|
16
16
|
contract: USDT_CONTRACT,
|
17
17
|
fromBlock: FORK_BLOCK_NUMBER - 10n,
|
18
|
+
useIndexer: false,
|
18
19
|
});
|
19
20
|
expect(events.length).toBe(261);
|
20
21
|
});
|
@@ -35,6 +36,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
35
36
|
const events = await getContractEvents({
|
36
37
|
contract: USDT_CONTRACT,
|
37
38
|
blockRange: 10n,
|
39
|
+
useIndexer: false,
|
38
40
|
});
|
39
41
|
expect(events.length).toBe(241);
|
40
42
|
|
@@ -42,6 +44,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
42
44
|
contract: USDT_CONTRACT,
|
43
45
|
fromBlock: FORK_BLOCK_NUMBER - 9n, // 1 less than range as fromBlock and toBlock are inclusive
|
44
46
|
toBlock: FORK_BLOCK_NUMBER,
|
47
|
+
useIndexer: false,
|
45
48
|
});
|
46
49
|
expect(explicitEvents.length).toEqual(events.length);
|
47
50
|
});
|
@@ -51,6 +54,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
51
54
|
contract: USDT_CONTRACT,
|
52
55
|
fromBlock: FORK_BLOCK_NUMBER - 49n,
|
53
56
|
blockRange: 20n,
|
57
|
+
useIndexer: false,
|
54
58
|
});
|
55
59
|
expect(eventsFromBlock.length).toBe(412);
|
56
60
|
|
@@ -58,6 +62,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
58
62
|
contract: USDT_CONTRACT,
|
59
63
|
toBlock: FORK_BLOCK_NUMBER - 30n,
|
60
64
|
blockRange: 20n,
|
65
|
+
useIndexer: false,
|
61
66
|
});
|
62
67
|
expect(eventsToBlock.length).toBe(eventsFromBlock.length);
|
63
68
|
|
@@ -65,6 +70,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
65
70
|
contract: USDT_CONTRACT,
|
66
71
|
fromBlock: FORK_BLOCK_NUMBER - 49n,
|
67
72
|
toBlock: FORK_BLOCK_NUMBER - 30n,
|
73
|
+
useIndexer: false,
|
68
74
|
});
|
69
75
|
expect(explicitEvents.length).toEqual(eventsFromBlock.length);
|
70
76
|
});
|
@@ -73,6 +79,7 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
73
79
|
const events = await getContractEvents({
|
74
80
|
contract: USDT_CONTRACT,
|
75
81
|
fromBlock: FORK_BLOCK_NUMBER - 100n,
|
82
|
+
useIndexer: false,
|
76
83
|
events: [
|
77
84
|
prepareEvent({
|
78
85
|
signature: "event Burn(address indexed burner, uint256 amount)",
|
@@ -86,6 +93,8 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
86
93
|
const events = await getContractEvents({
|
87
94
|
contract: USDT_CONTRACT,
|
88
95
|
fromBlock: FORK_BLOCK_NUMBER - 10n,
|
96
|
+
toBlock: FORK_BLOCK_NUMBER,
|
97
|
+
useIndexer: false,
|
89
98
|
events: [
|
90
99
|
prepareEvent({
|
91
100
|
signature: "event Burn(address indexed burner, uint256 amount)",
|
@@ -126,6 +135,8 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
126
135
|
const events = await getContractEvents({
|
127
136
|
contract: DOODLES_CONTRACT,
|
128
137
|
fromBlock: FORK_BLOCK_NUMBER - 1000n,
|
138
|
+
toBlock: FORK_BLOCK_NUMBER,
|
139
|
+
useIndexer: false,
|
129
140
|
events: [transferEvent()],
|
130
141
|
});
|
131
142
|
expect(events.length).toBe(38);
|
@@ -135,6 +146,8 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
135
146
|
const events = await getContractEvents({
|
136
147
|
contract: DOODLES_CONTRACT,
|
137
148
|
fromBlock: FORK_BLOCK_NUMBER - 1000n,
|
149
|
+
toBlock: FORK_BLOCK_NUMBER,
|
150
|
+
useIndexer: false,
|
138
151
|
events: [
|
139
152
|
transferEvent({
|
140
153
|
from: "0xB81965DdFdDA3923f292a47A1be83ba3A36B5133",
|
@@ -143,4 +156,87 @@ describe.runIf(process.env.TW_SECRET_KEY)("getEvents", () => {
|
|
143
156
|
});
|
144
157
|
expect(events.length).toBe(2);
|
145
158
|
});
|
159
|
+
|
160
|
+
// insight tests
|
161
|
+
|
162
|
+
it("should get events for blockHash using indexer", async () => {
|
163
|
+
const BLOCK_HASH =
|
164
|
+
"0xb0ad5ee7b4912b50e5a2d7993796944653a4c0632c57740fe4a7a1c61e426324";
|
165
|
+
const events = await getContractEvents({
|
166
|
+
contract: USDT_CONTRACT,
|
167
|
+
blockHash: BLOCK_HASH,
|
168
|
+
useIndexer: true,
|
169
|
+
});
|
170
|
+
|
171
|
+
expect(events.length).toBe(14);
|
172
|
+
});
|
173
|
+
|
174
|
+
it("should get individual events with extension no filter using indexer", async () => {
|
175
|
+
const events = await getContractEvents({
|
176
|
+
contract: DOODLES_CONTRACT,
|
177
|
+
fromBlock: FORK_BLOCK_NUMBER - 1000n,
|
178
|
+
toBlock: FORK_BLOCK_NUMBER,
|
179
|
+
events: [transferEvent()],
|
180
|
+
useIndexer: true,
|
181
|
+
});
|
182
|
+
expect(events.length).toBe(38);
|
183
|
+
});
|
184
|
+
|
185
|
+
it("should get events for signature using indexer", async () => {
|
186
|
+
const events = await getContractEvents({
|
187
|
+
contract: DOODLES_CONTRACT,
|
188
|
+
fromBlock: FORK_BLOCK_NUMBER - 1000n,
|
189
|
+
toBlock: FORK_BLOCK_NUMBER,
|
190
|
+
events: [
|
191
|
+
transferEvent({
|
192
|
+
from: "0xB81965DdFdDA3923f292a47A1be83ba3A36B5133",
|
193
|
+
}),
|
194
|
+
],
|
195
|
+
useIndexer: true,
|
196
|
+
});
|
197
|
+
|
198
|
+
expect(events.length).toBe(2);
|
199
|
+
});
|
200
|
+
|
201
|
+
it("should get specified events using indexer", async () => {
|
202
|
+
const events = await getContractEvents({
|
203
|
+
contract: USDT_CONTRACT,
|
204
|
+
fromBlock: FORK_BLOCK_NUMBER - 10n,
|
205
|
+
toBlock: FORK_BLOCK_NUMBER,
|
206
|
+
useIndexer: true,
|
207
|
+
events: [
|
208
|
+
prepareEvent({
|
209
|
+
signature: "event Burn(address indexed burner, uint256 amount)",
|
210
|
+
}),
|
211
|
+
prepareEvent({
|
212
|
+
signature: {
|
213
|
+
anonymous: false,
|
214
|
+
inputs: [
|
215
|
+
{
|
216
|
+
indexed: true,
|
217
|
+
internalType: "address",
|
218
|
+
name: "owner",
|
219
|
+
type: "address",
|
220
|
+
},
|
221
|
+
{
|
222
|
+
indexed: true,
|
223
|
+
internalType: "address",
|
224
|
+
name: "spender",
|
225
|
+
type: "address",
|
226
|
+
},
|
227
|
+
{
|
228
|
+
indexed: false,
|
229
|
+
internalType: "uint256",
|
230
|
+
name: "value",
|
231
|
+
type: "uint256",
|
232
|
+
},
|
233
|
+
],
|
234
|
+
name: "Approval",
|
235
|
+
type: "event",
|
236
|
+
},
|
237
|
+
}),
|
238
|
+
],
|
239
|
+
});
|
240
|
+
expect(events.length).toMatchInlineSnapshot("9");
|
241
|
+
});
|
146
242
|
});
|
@@ -1,18 +1,14 @@
|
|
1
|
-
/**
|
2
|
-
* 1. blockTime + contract (with abi) + no events -> logs with types and parsing *if* contract has abi defined
|
3
|
-
* 2. blockTime + contract (no abi) + no events -> logs with NO types but *with* parsing
|
4
|
-
* 3. blockTime + no contract + events -> logs with types and parsing (across all "addresses") (no contract filter)
|
5
|
-
* 4. blockTime + contract + events -> logs with types and parsing (filtered by contract address + event topics)
|
6
|
-
*/
|
7
|
-
|
8
1
|
import type {
|
9
2
|
Abi,
|
10
3
|
AbiEvent,
|
11
4
|
ExtractAbiEvent,
|
12
5
|
ExtractAbiEventNames,
|
13
6
|
} from "abitype";
|
7
|
+
import { type Log, formatLog } from "viem";
|
8
|
+
import { getChainServices } from "../../chains/utils.js";
|
14
9
|
import { resolveContractAbi } from "../../contract/actions/resolve-abi.js";
|
15
10
|
import type { ThirdwebContract } from "../../contract/contract.js";
|
11
|
+
import { getContractEvents as getContractEventsInsight } from "../../insight/get-events.js";
|
16
12
|
import { eth_blockNumber } from "../../rpc/actions/eth_blockNumber.js";
|
17
13
|
import {
|
18
14
|
type GetLogsBlockParams,
|
@@ -21,6 +17,7 @@ import {
|
|
21
17
|
} from "../../rpc/actions/eth_getLogs.js";
|
22
18
|
import { getRpcClient } from "../../rpc/rpc.js";
|
23
19
|
import { getAddress } from "../../utils/address.js";
|
20
|
+
import { type Hex, numberToHex } from "../../utils/encoding/hex.js";
|
24
21
|
import type { Prettify } from "../../utils/type-utils.js";
|
25
22
|
import { type PreparedEvent, prepareEvent } from "../prepare-event.js";
|
26
23
|
import { isAbiEvent } from "../utils.js";
|
@@ -34,6 +31,7 @@ export type GetContractEventsOptionsDirect<
|
|
34
31
|
contract: ThirdwebContract<abi>;
|
35
32
|
events?: abiEvents;
|
36
33
|
strict?: TStrict;
|
34
|
+
useIndexer?: boolean;
|
37
35
|
};
|
38
36
|
|
39
37
|
export type GetContractEventsOptions<
|
@@ -49,6 +47,10 @@ export type GetContractEventsResult<
|
|
49
47
|
TStrict extends boolean,
|
50
48
|
> = ParseEventLogsResult<abiEvents, TStrict>;
|
51
49
|
|
50
|
+
type GetLogsParamsExtra = {
|
51
|
+
signature?: string;
|
52
|
+
} & GetLogsParams;
|
53
|
+
|
52
54
|
/**
|
53
55
|
* Retrieves events from a contract based on the provided options.
|
54
56
|
* @param options - The options for retrieving events.
|
@@ -106,7 +108,13 @@ export async function getContractEvents<
|
|
106
108
|
>(
|
107
109
|
options: GetContractEventsOptions<abi, abiEvents, TStrict>,
|
108
110
|
): Promise<GetContractEventsResult<abiEvents, TStrict>> {
|
109
|
-
const {
|
111
|
+
const {
|
112
|
+
contract,
|
113
|
+
events,
|
114
|
+
blockRange,
|
115
|
+
useIndexer = true,
|
116
|
+
...restParams
|
117
|
+
} = options;
|
110
118
|
|
111
119
|
const rpcRequest = getRpcClient(contract);
|
112
120
|
|
@@ -164,7 +172,7 @@ export async function getContractEvents<
|
|
164
172
|
}
|
165
173
|
}
|
166
174
|
|
167
|
-
const logsParams:
|
175
|
+
const logsParams: GetLogsParamsExtra[] =
|
168
176
|
events && events.length > 0
|
169
177
|
? // if we have events passed in then we use those
|
170
178
|
events.map((e) => ({
|
@@ -175,9 +183,33 @@ export async function getContractEvents<
|
|
175
183
|
: // otherwise we want "all" events (aka not pass any topics at all)
|
176
184
|
[{ ...restParams, address: getAddress(contract.address) }];
|
177
185
|
|
178
|
-
|
179
|
-
|
180
|
-
|
186
|
+
let logs: Log[][] = [];
|
187
|
+
|
188
|
+
// try fetching from insight if available
|
189
|
+
if (useIndexer) {
|
190
|
+
try {
|
191
|
+
logs = await Promise.all(
|
192
|
+
logsParams.map((p) =>
|
193
|
+
getLogsFromInsight({
|
194
|
+
params: p,
|
195
|
+
contract,
|
196
|
+
}),
|
197
|
+
),
|
198
|
+
);
|
199
|
+
} catch (e) {
|
200
|
+
console.warn("Error fetching from insight", e);
|
201
|
+
// fetch from rpc
|
202
|
+
logs = await Promise.all(
|
203
|
+
logsParams.map((ethLogParams) => eth_getLogs(rpcRequest, ethLogParams)),
|
204
|
+
);
|
205
|
+
}
|
206
|
+
} else {
|
207
|
+
// fetch from rpc
|
208
|
+
logs = await Promise.all(
|
209
|
+
logsParams.map((ethLogParams) => eth_getLogs(rpcRequest, ethLogParams)),
|
210
|
+
);
|
211
|
+
}
|
212
|
+
|
181
213
|
const flattenLogs = logs
|
182
214
|
.flat()
|
183
215
|
.sort((a, b) => Number((a.blockNumber ?? 0n) - (b.blockNumber ?? 0n)));
|
@@ -186,3 +218,58 @@ export async function getContractEvents<
|
|
186
218
|
events: resolvedEvents,
|
187
219
|
});
|
188
220
|
}
|
221
|
+
|
222
|
+
async function getLogsFromInsight(options: {
|
223
|
+
params: GetLogsParamsExtra;
|
224
|
+
contract: ThirdwebContract<Abi>;
|
225
|
+
}): Promise<Log[]> {
|
226
|
+
const { params, contract } = options;
|
227
|
+
|
228
|
+
const chainServices = await getChainServices(contract.chain);
|
229
|
+
const insightEnabled = chainServices.some(
|
230
|
+
(c) => c.service === "insight" && c.enabled,
|
231
|
+
);
|
232
|
+
|
233
|
+
if (!insightEnabled) {
|
234
|
+
throw new Error(
|
235
|
+
`Insight is not available for chainId ${contract.chain.id}`,
|
236
|
+
);
|
237
|
+
}
|
238
|
+
|
239
|
+
const fromBlock =
|
240
|
+
typeof params.fromBlock === "bigint" ? Number(params.fromBlock) : undefined;
|
241
|
+
|
242
|
+
const toBlock =
|
243
|
+
typeof params.toBlock === "bigint" ? Number(params.toBlock) : undefined;
|
244
|
+
|
245
|
+
const r = await getContractEventsInsight({
|
246
|
+
client: contract.client,
|
247
|
+
chains: [contract.chain],
|
248
|
+
contractAddress: contract.address,
|
249
|
+
queryOptions: {
|
250
|
+
limit: 500,
|
251
|
+
filter_block_hash: params.blockHash,
|
252
|
+
filter_block_number_gte: fromBlock,
|
253
|
+
filter_block_number_lte: toBlock,
|
254
|
+
filter_topic_0: params.topics?.[0] as Hex | undefined,
|
255
|
+
filter_topic_1: params.topics?.[1] as Hex | undefined,
|
256
|
+
filter_topic_2: params.topics?.[2] as Hex | undefined,
|
257
|
+
filter_topic_3: params.topics?.[3] as Hex | undefined,
|
258
|
+
},
|
259
|
+
});
|
260
|
+
|
261
|
+
const cleanedEventData = r.map((tx) => ({
|
262
|
+
chainId: tx.chain_id,
|
263
|
+
blockNumber: numberToHex(Number(tx.block_number)),
|
264
|
+
blockHash: tx.block_hash as Hex,
|
265
|
+
blockTimestamp: tx.block_timestamp,
|
266
|
+
transactionHash: tx.transaction_hash as Hex,
|
267
|
+
transactionIndex: numberToHex(tx.transaction_index),
|
268
|
+
logIndex: numberToHex(tx.log_index),
|
269
|
+
address: tx.address,
|
270
|
+
data: tx.data as Hex,
|
271
|
+
topics: tx.topics as [`0x${string}`, ...`0x${string}`[]] | [] | undefined,
|
272
|
+
}));
|
273
|
+
|
274
|
+
return cleanedEventData.map((e) => formatLog(e));
|
275
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from "../insight/index.js";
|
package/src/exports/thirdweb.ts
CHANGED
package/src/extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.ts
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
import { readContract } from "../../../../../transaction/read-contract.js";
|
2
|
+
import type { BaseTransactionOptions } from "../../../../../transaction/types.js";
|
3
|
+
|
4
|
+
import { decodeAbiParameters } from "viem";
|
5
|
+
import type { Hex } from "../../../../../utils/encoding/hex.js";
|
6
|
+
import { detectMethod } from "../../../../../utils/bytecode/detectExtension.js";
|
7
|
+
|
8
|
+
export const FN_SELECTOR = "0x4a00cc48" as const;
|
9
|
+
const FN_INPUTS = [] as const;
|
10
|
+
const FN_OUTPUTS = [
|
11
|
+
{
|
12
|
+
type: "tuple[]",
|
13
|
+
components: [
|
14
|
+
{
|
15
|
+
type: "tuple",
|
16
|
+
name: "metadata",
|
17
|
+
components: [
|
18
|
+
{
|
19
|
+
type: "string",
|
20
|
+
name: "name",
|
21
|
+
},
|
22
|
+
{
|
23
|
+
type: "string",
|
24
|
+
name: "metadataURI",
|
25
|
+
},
|
26
|
+
{
|
27
|
+
type: "address",
|
28
|
+
name: "implementation",
|
29
|
+
},
|
30
|
+
],
|
31
|
+
},
|
32
|
+
{
|
33
|
+
type: "tuple[]",
|
34
|
+
name: "functions",
|
35
|
+
components: [
|
36
|
+
{
|
37
|
+
type: "bytes4",
|
38
|
+
name: "functionSelector",
|
39
|
+
},
|
40
|
+
{
|
41
|
+
type: "string",
|
42
|
+
name: "functionSignature",
|
43
|
+
},
|
44
|
+
],
|
45
|
+
},
|
46
|
+
],
|
47
|
+
},
|
48
|
+
] as const;
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Checks if the `getAllExtensions` method is supported by the given contract.
|
52
|
+
* @param availableSelectors An array of 4byte function selectors of the contract. You can get this in various ways, such as using "whatsabi" or if you have the ABI of the contract available you can use it to generate the selectors.
|
53
|
+
* @returns A boolean indicating if the `getAllExtensions` method is supported.
|
54
|
+
* @extension DYNAMIC-CONTRACTS
|
55
|
+
* @example
|
56
|
+
* ```ts
|
57
|
+
* import { isGetAllExtensionsSupported } from "thirdweb/extensions/dynamic-contracts";
|
58
|
+
* const supported = isGetAllExtensionsSupported(["0x..."]);
|
59
|
+
* ```
|
60
|
+
*/
|
61
|
+
export function isGetAllExtensionsSupported(availableSelectors: string[]) {
|
62
|
+
return detectMethod({
|
63
|
+
availableSelectors,
|
64
|
+
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
65
|
+
});
|
66
|
+
}
|
67
|
+
|
68
|
+
/**
|
69
|
+
* Decodes the result of the getAllExtensions function call.
|
70
|
+
* @param result - The hexadecimal result to decode.
|
71
|
+
* @returns The decoded result as per the FN_OUTPUTS definition.
|
72
|
+
* @extension DYNAMIC-CONTRACTS
|
73
|
+
* @example
|
74
|
+
* ```ts
|
75
|
+
* import { decodeGetAllExtensionsResult } from "thirdweb/extensions/dynamic-contracts";
|
76
|
+
* const result = decodeGetAllExtensionsResultResult("...");
|
77
|
+
* ```
|
78
|
+
*/
|
79
|
+
export function decodeGetAllExtensionsResult(result: Hex) {
|
80
|
+
return decodeAbiParameters(FN_OUTPUTS, result)[0];
|
81
|
+
}
|
82
|
+
|
83
|
+
/**
|
84
|
+
* Calls the "getAllExtensions" function on the contract.
|
85
|
+
* @param options - The options for the getAllExtensions function.
|
86
|
+
* @returns The parsed result of the function call.
|
87
|
+
* @extension DYNAMIC-CONTRACTS
|
88
|
+
* @example
|
89
|
+
* ```ts
|
90
|
+
* import { getAllExtensions } from "thirdweb/extensions/dynamic-contracts";
|
91
|
+
*
|
92
|
+
* const result = await getAllExtensions({
|
93
|
+
* contract,
|
94
|
+
* });
|
95
|
+
*
|
96
|
+
* ```
|
97
|
+
*/
|
98
|
+
export async function getAllExtensions(options: BaseTransactionOptions) {
|
99
|
+
return readContract({
|
100
|
+
contract: options.contract,
|
101
|
+
method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const,
|
102
|
+
params: [],
|
103
|
+
});
|
104
|
+
}
|
@@ -5,6 +5,7 @@ import type { ThirdwebClient } from "../../../client/client.js";
|
|
5
5
|
import { ZERO_ADDRESS } from "../../../constants/addresses.js";
|
6
6
|
import { getContract } from "../../../contract/contract.js";
|
7
7
|
import { CONTRACT_PUBLISHER_ADDRESS } from "../../../contract/deployment/publisher.js";
|
8
|
+
import { isGetAllExtensionsSupported } from "../../../extensions/dynamic-contracts/__generated__/IExtensionManager/read/getAllExtensions.js";
|
8
9
|
import { download } from "../../../storage/download.js";
|
9
10
|
import { upload } from "../../../storage/upload.js";
|
10
11
|
import type { BaseTransactionOptions } from "../../../transaction/types.js";
|
@@ -79,8 +80,14 @@ export function publishContract(
|
|
79
80
|
compositeAbi: options.metadata.compositeAbi,
|
80
81
|
constructorParams: options.metadata.constructorParams,
|
81
82
|
implConstructorParams: options.metadata.implConstructorParams,
|
82
|
-
defaultExtensions:
|
83
|
-
|
83
|
+
defaultExtensions:
|
84
|
+
routerType === "dynamic"
|
85
|
+
? options.metadata.defaultExtensions
|
86
|
+
: undefined,
|
87
|
+
defaultModules:
|
88
|
+
routerType === "modular"
|
89
|
+
? options.metadata.defaultModules
|
90
|
+
: undefined,
|
84
91
|
deployType: options.metadata.deployType,
|
85
92
|
description: options.metadata.description,
|
86
93
|
displayName: options.metadata.displayName,
|
@@ -131,6 +138,7 @@ function getRouterType(abi: Abi) {
|
|
131
138
|
.filter((f) => f.type === "function")
|
132
139
|
.map((f) => toFunctionSelector(f));
|
133
140
|
const isModule = isGetInstalledModulesSupported(fnSelectors);
|
134
|
-
|
135
|
-
|
141
|
+
const isDynamic = isGetAllExtensionsSupported(fnSelectors);
|
142
|
+
|
143
|
+
return isModule ? "modular" : isDynamic ? "dynamic" : "none";
|
136
144
|
}
|
@@ -0,0 +1,78 @@
|
|
1
|
+
import {
|
2
|
+
type GetV1EventsByContractAddressData,
|
3
|
+
type GetV1EventsByContractAddressResponse,
|
4
|
+
getV1EventsByContractAddress,
|
5
|
+
} from "@thirdweb-dev/insight";
|
6
|
+
import type { AbiEvent } from "ox/AbiEvent";
|
7
|
+
import { stringify } from "viem";
|
8
|
+
import type { Chain } from "../chains/types.js";
|
9
|
+
import type { ThirdwebClient } from "../client/client.js";
|
10
|
+
import type { PreparedEvent } from "../event/prepare-event.js";
|
11
|
+
import { getThirdwebDomains } from "../utils/domains.js";
|
12
|
+
import { getClientFetch } from "../utils/fetch.js";
|
13
|
+
|
14
|
+
export type ContractEvent = NonNullable<
|
15
|
+
GetV1EventsByContractAddressResponse["data"]
|
16
|
+
>[number];
|
17
|
+
|
18
|
+
/**
|
19
|
+
* Get contract events
|
20
|
+
* @example
|
21
|
+
* ```ts
|
22
|
+
* import { Insight } from "thirdweb";
|
23
|
+
*
|
24
|
+
* const events = await Insight.getContractEvents({
|
25
|
+
* client,
|
26
|
+
* chains: [sepolia],
|
27
|
+
* contractAddress: "0x1234567890123456789012345678901234567890",
|
28
|
+
* event: transferEvent(),
|
29
|
+
* decodeLogs: true,
|
30
|
+
* });
|
31
|
+
* ```
|
32
|
+
* @insight
|
33
|
+
*/
|
34
|
+
export async function getContractEvents(options: {
|
35
|
+
client: ThirdwebClient;
|
36
|
+
chains: Chain[];
|
37
|
+
contractAddress: string;
|
38
|
+
event?: PreparedEvent<AbiEvent>;
|
39
|
+
decodeLogs?: boolean;
|
40
|
+
queryOptions?: GetV1EventsByContractAddressData["query"];
|
41
|
+
}): Promise<ContractEvent[]> {
|
42
|
+
const { client, chains, contractAddress, event, queryOptions, decodeLogs } =
|
43
|
+
options;
|
44
|
+
|
45
|
+
const defaultQueryOptions: GetV1EventsByContractAddressData["query"] = {
|
46
|
+
chain: chains.map((chain) => chain.id),
|
47
|
+
limit: 100,
|
48
|
+
decode: decodeLogs,
|
49
|
+
};
|
50
|
+
|
51
|
+
if (event) {
|
52
|
+
defaultQueryOptions.filter_topic_0 = event.topics[0];
|
53
|
+
defaultQueryOptions.filter_topic_1 = event.topics[1];
|
54
|
+
defaultQueryOptions.filter_topic_2 = event.topics[2];
|
55
|
+
defaultQueryOptions.filter_topic_3 = event.topics[3];
|
56
|
+
}
|
57
|
+
|
58
|
+
const result = await getV1EventsByContractAddress({
|
59
|
+
baseUrl: `https://${getThirdwebDomains().insight}`,
|
60
|
+
fetch: getClientFetch(client),
|
61
|
+
path: {
|
62
|
+
contractAddress,
|
63
|
+
},
|
64
|
+
query: {
|
65
|
+
chain: chains.map((chain) => chain.id),
|
66
|
+
...defaultQueryOptions,
|
67
|
+
...queryOptions,
|
68
|
+
},
|
69
|
+
});
|
70
|
+
|
71
|
+
if (result.error) {
|
72
|
+
throw new Error(
|
73
|
+
`${result.response.status} ${result.response.statusText} - ${result.error ? stringify(result.error) : "Unknown error"}`,
|
74
|
+
);
|
75
|
+
}
|
76
|
+
|
77
|
+
return result.data?.data ?? [];
|
78
|
+
}
|