Skip to content

Commit 5fac132

Browse files
feat: add getCurrentTimeMs in web3libadapter for assertCompletableExc… (#961)
* feat: add getCurrentTimeMs in web3libadapter for assertCompletableExchange * Update packages/core-sdk/src/exchanges/handler.ts Co-authored-by: Ludovic Levalleux <[email protected]> --------- Co-authored-by: Ludovic Levalleux <[email protected]>
1 parent 40d4ae1 commit 5fac132

File tree

8 files changed

+76
-62
lines changed

8 files changed

+76
-62
lines changed

packages/common/src/types/web3-lib-adapter.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { BigNumberish } from "@ethersproject/bignumber";
22

3-
export type Log = {
4-
data: string;
5-
topics: string[];
6-
};
3+
export type Log = { data: string; topics: string[] };
74

85
export type TransactionRequest = Partial<{
96
to: string;
@@ -48,4 +45,5 @@ export interface Web3LibAdapter {
4845
call(transactionRequest: TransactionRequest): Promise<string>;
4946
send(rpcMethod: string, payload: unknown[]): Promise<string>;
5047
getTransactionReceipt(txHash: string): Promise<TransactionReceipt>;
48+
getCurrentTimeMs(): Promise<number>;
5149
}

packages/common/tests/mocks.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,7 @@ export function mockOfferStruct(overrides?: Partial<OfferStruct>): OfferStruct {
3636
metadataUri: IPFS_URI,
3737
metadataHash: IPFS_HASH,
3838
priceType: PriceType.Static,
39-
royaltyInfo: [
40-
{
41-
recipients: [AddressZero],
42-
bps: [0]
43-
}
44-
],
39+
royaltyInfo: [{ recipients: [AddressZero], bps: [0] }],
4540
...overrides
4641
};
4742
}
@@ -158,10 +153,10 @@ export class MockWeb3LibAdapter implements Web3LibAdapter {
158153

159154
constructor(returnValues: Partial<MockedWeb3LibReturnValues> = {}) {
160155
this.uuid = crypto.randomUUID();
161-
this._returnValues = {
162-
...defaultMockedReturnValues,
163-
...returnValues
164-
};
156+
this._returnValues = { ...defaultMockedReturnValues, ...returnValues };
157+
}
158+
getCurrentTimeMs(): Promise<number> {
159+
return Promise.resolve(Date.now());
165160
}
166161
async getTransactionReceipt(txHash: string): Promise<TransactionReceipt> {
167162
this.getTransactionReceiptArgs.push(txHash);

packages/core-sdk/src/exchanges/handler.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,12 @@ export async function completeExchange(
218218
args.web3Lib.getSignerAddress()
219219
]);
220220

221-
assertCompletableExchange(args.exchangeId, exchange, signerAddress);
221+
await assertCompletableExchange(
222+
args.exchangeId,
223+
exchange,
224+
signerAddress,
225+
args.web3Lib
226+
);
222227

223228
const transactionRequest = {
224229
to: args.contractAddress,
@@ -257,15 +262,18 @@ export async function completeExchangeBatch(
257262
): Promise<TransactionRequest | TransactionResponse> {
258263
const [exchanges, signerAddress] = await Promise.all([
259264
getExchanges(args.subgraphUrl, {
260-
exchangesFilter: {
261-
id_in: args.exchangeIds.map((id) => id.toString())
262-
}
265+
exchangesFilter: { id_in: args.exchangeIds.map((id) => id.toString()) }
263266
}),
264267
args.web3Lib.getSignerAddress()
265268
]);
266269

267270
for (const exchange of exchanges) {
268-
assertCompletableExchange(exchange.id, exchange, signerAddress);
271+
await assertCompletableExchange(
272+
exchange.id,
273+
exchange,
274+
signerAddress,
275+
args.web3Lib
276+
);
269277
}
270278

271279
const transactionRequest = {
@@ -522,10 +530,11 @@ function assertSignerIsBuyerOrAssistant(
522530
return { isSignerBuyer, isSignerAssistant };
523531
}
524532

525-
function assertCompletableExchange(
533+
async function assertCompletableExchange(
526534
exchangeId: BigNumberish,
527535
exchange: ExchangeFieldsFragment | null,
528-
signer: string
536+
signer: string,
537+
web3Lib: Web3LibAdapter
529538
) {
530539
assertExchange(exchangeId, exchange);
531540

@@ -535,8 +544,9 @@ function assertCompletableExchange(
535544
);
536545

537546
if (isSignerAssistant && !isSignerBuyer) {
547+
const now = await web3Lib.getCurrentTimeMs();
538548
const elapsedSinceRedeemMS =
539-
Date.now() - Number(exchange.redeemedDate || "0") * 1000;
549+
now - Number(exchange.redeemedDate || "0") * 1000;
540550
const didDisputePeriodElapse =
541551
elapsedSinceRedeemMS >
542552
Number(exchange.offer.disputePeriodDuration) * 1000;

packages/eth-connect-sdk/src/eth-connect-adapter.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ export class EthConnectAdapter implements Web3LibAdapter {
3636
this._externalFeatures = externalFeatures;
3737
}
3838

39+
async getCurrentTimeMs(): Promise<number> {
40+
const { timestamp } = await this._requestManager.eth_getBlockByNumber(
41+
"latest",
42+
false
43+
);
44+
return Number(timestamp.valueOf()) * 1000; // Convert seconds to milliseconds
45+
}
46+
3947
public async getSignerAddress() {
4048
if (this._externalFeatures?.getSignerAddress) {
4149
const address = await this._externalFeatures?.getSignerAddress();
@@ -97,10 +105,7 @@ export class EthConnectAdapter implements Web3LibAdapter {
97105
// Use standard requestManager to fetch blockchain information
98106
const blockNumber = await this._requestManager.eth_blockNumber();
99107
return this._requestManager.eth_call(
100-
{
101-
data: transactionRequest.data,
102-
to: transactionRequest.to
103-
},
108+
{ data: transactionRequest.data, to: transactionRequest.to },
104109
blockNumber
105110
);
106111
}

packages/eth-connect-sdk/tests/index.test.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const CALL_RET = "call_ret";
1414
const TRANSACTION_COUNT = 64;
1515
const GAS_USED = "87654";
1616
const TX_HASH = "transactionHash";
17+
const nowInSec = Math.floor(Date.now() / 1000);
1718

1819
test("imports EthConnectAdapter", () => {
1920
expect(EthConnectAdapter).toBeTruthy();
@@ -161,6 +162,17 @@ test("EthConnectAdapter getTransactionReceipt", async () => {
161162
expect(txReceipt.transactionHash).toEqual(TX_HASH);
162163
});
163164

165+
test("EthConnectAdapter getCurrentTimeMs", async () => {
166+
const requestManager = mockRequestManager();
167+
const externalFeatures = mockExternalFeatures();
168+
const ethConnectAdapter = new EthConnectAdapter(
169+
requestManager,
170+
externalFeatures
171+
);
172+
const nowMs = await ethConnectAdapter.getCurrentTimeMs();
173+
expect(nowMs).toBe(nowInSec * 1000); // Convert seconds to milliseconds
174+
});
175+
164176
function mockSigner(wallet: string): RequestManager {
165177
return mockRequestManager(wallet);
166178
}
@@ -187,7 +199,10 @@ function mockRequestManager(wallet?: string): RequestManager {
187199
},
188200
eth_accounts: async () => (wallet ? [wallet] : WALLETS),
189201
eth_sendTransaction: async (t: any) => TX_HASH,
190-
sendAsync: async (t: any) => TX_HASH
202+
sendAsync: async (t: any) => TX_HASH,
203+
eth_getBlockByNumber: async (blockNumber: string, fullTx: boolean) => {
204+
return { timestamp: nowInSec };
205+
}
191206
} as unknown as RequestManager;
192207
}
193208

@@ -200,7 +215,5 @@ function mockExternalFeatures(signerAddress?: string): ExternalFeatures {
200215
}
201216
} as ExternalFeatures;
202217
}
203-
return {
204-
delay: async (ms: number) => undefined
205-
} as ExternalFeatures;
218+
return { delay: async (ms: number) => undefined } as ExternalFeatures;
206219
}

packages/ethers-sdk/src/ethers-adapter.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ export class EthersAdapter implements Web3LibAdapter {
4040
: this._provider.getSigner();
4141
}
4242

43+
async getCurrentTimeMs(): Promise<number> {
44+
const { timestamp } = await this._provider.getBlock("latest");
45+
return timestamp * 1000; // Convert seconds to milliseconds
46+
}
47+
4348
public async getSignerAddress() {
4449
return this._signer.getAddress();
4550
}

packages/ethers-sdk/tests/index.test.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const BLOCK_NUMBER = "42";
1212
const CALL_RET = "call_ret";
1313
const GAS_USED = "87654";
1414
const TX_HASH = "transactionHash";
15+
const nowInSec = Math.floor(Date.now() / 1000);
1516

1617
test("imports EthersAdapter", () => {
1718
expect(EthersAdapter).toBeTruthy();
@@ -24,15 +25,15 @@ test("EthersAdapter constructor", () => {
2425
expect(ethersAdapter).toBeTruthy();
2526
});
2627

27-
test("EthConnectAdapter getSignerAddress without signer", async () => {
28+
test("EthersAdapter getSignerAddress without signer", async () => {
2829
const provider = mockProvider();
2930
const ethersAdapter = new EthersAdapter(provider);
3031
expect(ethersAdapter).toBeTruthy();
3132
const signerAddress = await ethersAdapter.getSignerAddress();
3233
expect(signerAddress).toEqual(WALLETS[0]);
3334
});
3435

35-
test("EthConnectAdapter getSignerAddress with signer", async () => {
36+
test("EthersAdapter getSignerAddress with signer", async () => {
3637
const provider = mockProvider();
3738
const signer = mockSigner(WALLETS[2]);
3839
const ethersAdapter = new EthersAdapter(provider, signer);
@@ -41,6 +42,14 @@ test("EthConnectAdapter getSignerAddress with signer", async () => {
4142
expect(signerAddress).toEqual(WALLETS[2]);
4243
});
4344

45+
test("EthersAdapter getCurrentTimeMs", async () => {
46+
const provider = mockProvider();
47+
const ethersAdapter = new EthersAdapter(provider);
48+
expect(ethersAdapter).toBeTruthy();
49+
const nowMs = await ethersAdapter.getCurrentTimeMs();
50+
expect(nowMs).toBe(nowInSec * 1000); // Convert seconds to milliseconds
51+
});
52+
4453
function mockProvider(): Provider {
4554
return {
4655
getBalance: async () => {
@@ -58,7 +67,8 @@ function mockProvider(): Provider {
5867
},
5968
send: async () => TX_HASH,
6069
getSigner: () => mockSigner(WALLETS[0]),
61-
getCode: async () => "0x"
70+
getCode: async () => "0x",
71+
getBlock: async () => ({ timestamp: nowInSec })
6272
} as unknown as Provider;
6373
}
6474

@@ -67,8 +77,5 @@ function mockSigner(wallet: string): Signer {
6777
getAddress: async () => wallet,
6878
getChainId: async () => CHAIN_ID
6979
};
70-
return {
71-
...signer,
72-
connect: () => signer
73-
} as unknown as Signer;
80+
return { ...signer, connect: () => signer } as unknown as Signer;
7481
}

packages/react-kit/src/lib/signer/externalSigner.ts

Lines changed: 6 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,7 @@ const getDefaultHandleSignerFunction = <R>({
3838
}
3939
}
4040
window.addEventListener("message", onMessageReceived);
41-
window.parent.postMessage(
42-
{
43-
function: functionName,
44-
args
45-
},
46-
parentOrigin
47-
);
41+
window.parent.postMessage({ function: functionName, args }, parentOrigin);
4842
});
4943
};
5044

@@ -55,6 +49,7 @@ const getExternalWeb3LibAdapterListener = ({
5549
}): Web3LibAdapter => {
5650
return {
5751
uuid: crypto.randomUUID(),
52+
getCurrentTimeMs: () => Promise.resolve(Date.now()),
5853
getSignerAddress: (): Promise<string> => {
5954
return getDefaultHandleSignerFunction<string>({
6055
parentOrigin,
@@ -145,10 +140,7 @@ const getExternalWeb3LibAdapterListener = ({
145140
}
146141
window.addEventListener("message", onMessageReceived);
147142
window.parent.postMessage(
148-
{
149-
function: functionName,
150-
args: [transactionRequest]
151-
},
143+
{ function: functionName, args: [transactionRequest] },
152144
parentOrigin
153145
);
154146
});
@@ -289,10 +281,7 @@ const getExternalSignerListener = ({
289281
}
290282
window.addEventListener("message", onMessageReceived);
291283
window.parent.postMessage(
292-
{
293-
function: functionName,
294-
args: [transactionRequest]
295-
},
284+
{ function: functionName, args: [transactionRequest] },
296285
parentOrigin
297286
);
298287
});
@@ -330,11 +319,7 @@ const getExternalSignerListener = ({
330319
): ReturnType<Signer["populateTransaction"]> => {
331320
return getDefaultHandleSignerFunction<
332321
ReturnType<Signer["populateTransaction"]>
333-
>({
334-
parentOrigin,
335-
functionName: "populateTransaction",
336-
args
337-
});
322+
>({ parentOrigin, functionName: "populateTransaction", args });
338323
},
339324
estimateGas: async (...args: any[]): ReturnType<Signer["estimateGas"]> => {
340325
return getDefaultHandleSignerFunction<ReturnType<Signer["estimateGas"]>>({
@@ -353,11 +338,7 @@ const getExternalSignerListener = ({
353338
_checkProvider: async (...args: any[]): Promise<void> => {
354339
return getDefaultHandleSignerFunction<
355340
ReturnType<Signer["_checkProvider"]>
356-
>({
357-
parentOrigin,
358-
functionName: "_checkProvider",
359-
args
360-
});
341+
>({ parentOrigin, functionName: "_checkProvider", args });
361342
},
362343
connect: (..._args: any[]): ReturnType<Signer["connect"]> => {
363344
// TODO: how can we implement this?

0 commit comments

Comments
 (0)