Skip to content

Commit 1dad77f

Browse files
kien-ngoIDubuque
authored andcommitted
[SDK] Perf improvements for erc-20 methods (#1814)
Signed-off-by: Kien Ngo <kenseverus@gmail.com>
1 parent 4a2a416 commit 1dad77f

File tree

6 files changed

+94
-67
lines changed

6 files changed

+94
-67
lines changed

.changeset/little-jars-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@thirdweb-dev/sdk": patch
3+
---
4+
5+
[SDK] Perf inmprovement for erc-20 methods

packages/sdk/src/evm/core/classes/erc-20-batch-mintable.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,18 @@ export class Erc20BatchMintable implements DetectableFeature {
5757
*/
5858
to = /* @__PURE__ */ buildTransactionFunction(
5959
async (args: TokenMintInput[]) => {
60-
const encoded: string[] = [];
6160
const contractEncoder = new ContractEncoder(this.contractWrapper);
62-
63-
for (const arg of args) {
64-
encoded.push(
65-
contractEncoder.encode("mintTo", [
66-
await resolveAddress(arg.toAddress),
67-
await this.erc20.normalizeAmount(arg.amount),
61+
const _items = await Promise.all(
62+
args.map((item) =>
63+
Promise.all([
64+
resolveAddress(item.toAddress),
65+
this.erc20.normalizeAmount(item.amount),
6866
]),
69-
);
70-
}
67+
),
68+
);
69+
const encoded = _items.map(([address, amount]) =>
70+
contractEncoder.encode("mintTo", [address, amount]),
71+
);
7172

7273
return Transaction.fromContractWrapper({
7374
contractWrapper: this.contractWrapper,

packages/sdk/src/evm/core/classes/erc-20-burnable.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ export class Erc20Burnable implements DetectableFeature {
6262
return Transaction.fromContractWrapper({
6363
contractWrapper: this.contractWrapper,
6464
method: "burnFrom",
65-
args: [
66-
await resolveAddress(holder),
67-
await this.erc20.normalizeAmount(amount),
68-
],
65+
args: await Promise.all([
66+
resolveAddress(holder),
67+
this.erc20.normalizeAmount(amount),
68+
]),
6969
});
7070
},
7171
);

packages/sdk/src/evm/core/classes/erc-20-history.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,20 @@ export class TokenERC20History {
5555
balances[to] = balances[to].add(amount);
5656
}
5757
});
58-
return Promise.all(
59-
Object.keys(balances).map(async (addr) => ({
60-
holder: addr,
61-
balance: await fetchCurrencyValue(
58+
59+
const entries = Object.entries(balances);
60+
const results = await Promise.all(
61+
entries.map(([, value]) =>
62+
fetchCurrencyValue(
6263
this.contractWrapper.getProvider(),
6364
this.contractWrapper.address,
64-
balances[addr],
65+
value,
6566
),
66-
})),
67+
),
6768
);
69+
return entries.map(([addr], index) => ({
70+
holder: addr,
71+
balance: results[index],
72+
}));
6873
}
6974
}

packages/sdk/src/evm/core/classes/erc-20-mintable.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ export class Erc20Mintable implements DetectableFeature {
6666
return Transaction.fromContractWrapper({
6767
contractWrapper: this.contractWrapper,
6868
method: "mintTo",
69-
args: [
70-
await resolveAddress(to),
71-
await this.erc20.normalizeAmount(amount),
72-
],
69+
args: await Promise.all([
70+
resolveAddress(to),
71+
this.erc20.normalizeAmount(amount),
72+
]),
7373
});
7474
}
7575

packages/sdk/src/evm/core/classes/erc-20-signature-mintable.ts

Lines changed: 60 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,10 @@ export class Erc20SignatureMintable implements DetectableFeature {
6363
async (signedPayload: SignedPayload20) => {
6464
const mintRequest = signedPayload.payload;
6565
const signature = signedPayload.signature;
66-
const message = await this.mapPayloadToContractStruct(mintRequest);
67-
const overrides = await this.contractWrapper.getCallOverrides();
66+
const [message, overrides] = await Promise.all([
67+
this.mapPayloadToContractStruct(mintRequest),
68+
this.contractWrapper.getCallOverrides(),
69+
]);
6870
// TODO: Transaction Sequence Pattern
6971
await setErc20Allowance(
7072
this.contractWrapper,
@@ -89,22 +91,23 @@ export class Erc20SignatureMintable implements DetectableFeature {
8991
*/
9092
mintBatch = /* @__PURE__ */ buildTransactionFunction(
9193
async (signedPayloads: SignedPayload20[]) => {
92-
const contractPayloads = await Promise.all(
93-
signedPayloads.map(async (s) => {
94-
const message = await this.mapPayloadToContractStruct(s.payload);
95-
const signature = s.signature;
96-
const price = s.payload.price;
97-
if (BigNumber.from(price).gt(0)) {
98-
throw new Error(
99-
"Can only batch free mints. For mints with a price, use regular mint()",
100-
);
101-
}
102-
return {
103-
message,
104-
signature,
105-
};
106-
}),
94+
const messages = await Promise.all(
95+
signedPayloads.map((s) => this.mapPayloadToContractStruct(s.payload)),
10796
);
97+
const contractPayloads = signedPayloads.map((s, index) => {
98+
const message = messages[index];
99+
const signature = s.signature;
100+
const price = s.payload.price;
101+
if (BigNumber.from(price).gt(0)) {
102+
throw new Error(
103+
"Can only batch free mints. For mints with a price, use regular mint()",
104+
);
105+
}
106+
return {
107+
message,
108+
signature,
109+
};
110+
});
108111

109112
const contractEncoder = new ContractEncoder(this.contractWrapper);
110113
const encoded = contractPayloads.map((p) => {
@@ -204,21 +207,30 @@ export class Erc20SignatureMintable implements DetectableFeature {
204207
await this.contractWrapper.getSignerAddress(),
205208
);
206209

207-
const parsedRequests: FilledSignaturePayload20[] = await Promise.all(
208-
payloadsToSign.map((m) => Signature20PayloadInput.parseAsync(m)),
209-
);
210+
const [chainId, name, parsedRequests]: [
211+
number,
212+
string,
213+
FilledSignaturePayload20[],
214+
] = await Promise.all([
215+
this.contractWrapper.getChainID(),
216+
this.contractWrapper.read("name", []), // ERC20Permit (EIP-712) spec differs from signature mint 721, 1155.
217+
Promise.all(
218+
payloadsToSign.map((m) => Signature20PayloadInput.parseAsync(m)),
219+
),
220+
]);
210221

211-
const chainId = await this.contractWrapper.getChainID();
212222
const signer = this.contractWrapper.getSigner();
213223
invariant(signer, "No signer available");
214224

215-
// ERC20Permit (EIP-712) spec differs from signature mint 721, 1155.
216-
const name = await this.contractWrapper.read("name", []);
217-
218-
return await Promise.all(
219-
parsedRequests.map(async (m) => {
220-
const finalPayload = await Signature20PayloadOutput.parseAsync(m);
221-
const signature = await this.contractWrapper.signTypedData(
225+
const finalPayloads = await Promise.all(
226+
parsedRequests.map((m) => Signature20PayloadOutput.parseAsync(m)),
227+
);
228+
const contractStructs = await Promise.all(
229+
finalPayloads.map((payload) => this.mapPayloadToContractStruct(payload)),
230+
);
231+
const signatures = await Promise.all(
232+
contractStructs.map((struct) =>
233+
this.contractWrapper.signTypedData(
222234
signer,
223235
{
224236
name,
@@ -227,14 +239,18 @@ export class Erc20SignatureMintable implements DetectableFeature {
227239
verifyingContract: this.contractWrapper.address,
228240
},
229241
{ MintRequest: MintRequest20 },
230-
await this.mapPayloadToContractStruct(finalPayload),
231-
);
232-
return {
233-
payload: finalPayload,
234-
signature: signature.toString(),
235-
};
236-
}),
242+
struct,
243+
),
244+
),
237245
);
246+
return parsedRequests.map((m, index) => {
247+
const finalPayload = finalPayloads[index];
248+
const signature = signatures[index];
249+
return {
250+
payload: finalPayload,
251+
signature: signature.toString(),
252+
};
253+
});
238254
}
239255

240256
/** ******************************
@@ -251,15 +267,15 @@ export class Erc20SignatureMintable implements DetectableFeature {
251267
private async mapPayloadToContractStruct(
252268
mintRequest: PayloadWithUri20,
253269
): Promise<ITokenERC20.MintRequestStructOutput> {
254-
const normalizedPrice = await normalizePriceValue(
255-
this.contractWrapper.getProvider(),
256-
mintRequest.price,
257-
mintRequest.currencyAddress,
258-
);
259-
const amountWithDecimals = utils.parseUnits(
260-
mintRequest.quantity,
261-
await this.contractWrapper.read("decimals", []),
262-
);
270+
const [normalizedPrice, decimals] = await Promise.all([
271+
normalizePriceValue(
272+
this.contractWrapper.getProvider(),
273+
mintRequest.price,
274+
mintRequest.currencyAddress,
275+
),
276+
this.contractWrapper.read("decimals", []),
277+
]);
278+
const amountWithDecimals = utils.parseUnits(mintRequest.quantity, decimals);
263279
return {
264280
to: mintRequest.to,
265281
primarySaleRecipient: mintRequest.primarySaleRecipient,

0 commit comments

Comments
 (0)