genlayer-js 0.4.8 → 0.6.0
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/CHANGELOG.md +14 -0
- package/README.md +1 -0
- package/dist/index.cjs +77 -21
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +74 -18
- package/dist/types/index.cjs +2 -2
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.js +1 -1
- package/package.json +1 -1
- package/src/accounts/actions.ts +2 -3
- package/src/client/client.ts +51 -13
- package/src/contracts/actions.ts +51 -12
- package/src/global.d.ts +7 -0
- package/src/types/clients.ts +2 -1
- package/tests/client.test.ts +33 -1
- package/tsconfig.json +1 -1
- /package/dist/{chunk-M7SA3INM.js → chunk-G7EQ6KPE.js} +0 -0
- /package/dist/{chunk-YI62SDKV.cjs → chunk-X6WK4DK4.cjs} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## 0.6.0 (2025-01-09)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add stateStatus in readContract ([#50](https://github.com/yeagerai/genlayer-js/issues/50)) ([a9bcf8d](https://github.com/yeagerai/genlayer-js/commit/a9bcf8d83890448b85282ceb0c33060a19ea4e9a))
|
|
9
|
+
|
|
10
|
+
## 0.5.0 (2025-01-08)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* add customtransport to use both wallet and local private keys ([#48](https://github.com/yeagerai/genlayer-js/issues/48)) ([905a123](https://github.com/yeagerai/genlayer-js/commit/905a12358c154e6ae865773b809952c8cc9c75b9))
|
|
16
|
+
|
|
3
17
|
## 0.4.8 (2024-12-18)
|
|
4
18
|
|
|
5
19
|
|
package/README.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
var _chunkIINRDYKFcjs = require('./chunk-IINRDYKF.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
var
|
|
7
|
+
var _chunkX6WK4DK4cjs = require('./chunk-X6WK4DK4.cjs');
|
|
8
8
|
require('./chunk-75ZPJI57.cjs');
|
|
9
9
|
|
|
10
10
|
// src/client/client.ts
|
|
@@ -22,14 +22,14 @@ function accountActions(client) {
|
|
|
22
22
|
params: [address, amount]
|
|
23
23
|
});
|
|
24
24
|
},
|
|
25
|
-
getCurrentNonce: async ({ address }) => {
|
|
25
|
+
getCurrentNonce: async ({ address, block = "latest" }) => {
|
|
26
26
|
const addressToUse = address || _optionalChain([client, 'access', _3 => _3.account, 'optionalAccess', _4 => _4.address]);
|
|
27
27
|
if (!addressToUse) {
|
|
28
28
|
throw new Error("No address provided and no account is connected");
|
|
29
29
|
}
|
|
30
30
|
return client.request({
|
|
31
31
|
method: "eth_getTransactionCount",
|
|
32
|
-
params: [addressToUse]
|
|
32
|
+
params: [addressToUse, block]
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -76,7 +76,7 @@ function decodeImpl(data, index) {
|
|
|
76
76
|
case BigInt(SPECIAL_ADDR): {
|
|
77
77
|
const res = data.slice(index.i, index.i + 20);
|
|
78
78
|
index.i += 20;
|
|
79
|
-
return new (0,
|
|
79
|
+
return new (0, _chunkX6WK4DK4cjs.Address)(res);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
const type = Number(cur & 0xffn) & (1 << BITS_IN_TYPE) - 1;
|
|
@@ -241,7 +241,7 @@ function encodeImpl(to, data) {
|
|
|
241
241
|
}
|
|
242
242
|
} else if (data instanceof Map) {
|
|
243
243
|
encodeMap(to, data);
|
|
244
|
-
} else if (data instanceof
|
|
244
|
+
} else if (data instanceof _chunkX6WK4DK4cjs.Address) {
|
|
245
245
|
to.push(SPECIAL_ADDR);
|
|
246
246
|
for (const c of data.bytes) {
|
|
247
247
|
to.push(c);
|
|
@@ -265,9 +265,6 @@ function encode(data) {
|
|
|
265
265
|
function serialize(data) {
|
|
266
266
|
return _viem.toRlp.call(void 0, data.map((param) => _viem.toHex.call(void 0, param)));
|
|
267
267
|
}
|
|
268
|
-
function encodeAndSerialize(data) {
|
|
269
|
-
return serialize([encode(data)]);
|
|
270
|
-
}
|
|
271
268
|
|
|
272
269
|
// src/contracts/actions.ts
|
|
273
270
|
var contractActions = (client) => {
|
|
@@ -290,12 +287,14 @@ var contractActions = (client) => {
|
|
|
290
287
|
};
|
|
291
288
|
var overrideContractActions = (client) => {
|
|
292
289
|
client.readContract = async (args) => {
|
|
293
|
-
const { account, address, functionName, args: params } = args;
|
|
294
|
-
const encodedData =
|
|
290
|
+
const { account, address, functionName, args: params, stateStatus = "ACCEPTED" /* ACCEPTED */ } = args;
|
|
291
|
+
const encodedData = [encode({ method: functionName, args: params }), stateStatus];
|
|
292
|
+
const serializedData = serialize(encodedData);
|
|
293
|
+
const senderAddress = _nullishCoalesce(_optionalChain([account, 'optionalAccess', _5 => _5.address]), () => ( _optionalChain([client, 'access', _6 => _6.account, 'optionalAccess', _7 => _7.address])));
|
|
295
294
|
const requestParams = {
|
|
296
295
|
to: address,
|
|
297
|
-
from:
|
|
298
|
-
data:
|
|
296
|
+
from: senderAddress,
|
|
297
|
+
data: serializedData
|
|
299
298
|
};
|
|
300
299
|
const result = await client.request({
|
|
301
300
|
method: "eth_call",
|
|
@@ -313,12 +312,24 @@ var overrideContractActions = (client) => {
|
|
|
313
312
|
const data = [encode({ method: functionName, args: params }), leaderOnly];
|
|
314
313
|
const serializedData = serialize(data);
|
|
315
314
|
const senderAccount = account || client.account;
|
|
315
|
+
if (_optionalChain([senderAccount, 'optionalAccess', _8 => _8.type]) !== "local") {
|
|
316
|
+
const transaction = {
|
|
317
|
+
from: _optionalChain([senderAccount, 'optionalAccess', _9 => _9.address]),
|
|
318
|
+
to: address,
|
|
319
|
+
data: serializedData,
|
|
320
|
+
value: `0x${value.toString(16)}`
|
|
321
|
+
};
|
|
322
|
+
return await client.request({
|
|
323
|
+
method: "eth_sendTransaction",
|
|
324
|
+
params: [transaction]
|
|
325
|
+
});
|
|
326
|
+
}
|
|
316
327
|
if (!senderAccount) {
|
|
317
328
|
throw new Error(
|
|
318
329
|
"No account set. Configure the client with an account or pass an account to this function."
|
|
319
330
|
);
|
|
320
331
|
}
|
|
321
|
-
if (!_optionalChain([senderAccount, 'optionalAccess',
|
|
332
|
+
if (!_optionalChain([senderAccount, 'optionalAccess', _10 => _10.signTransaction])) {
|
|
322
333
|
throw new Error("Account does not support signTransaction");
|
|
323
334
|
}
|
|
324
335
|
const nonce = await client.getCurrentNonce({ address: senderAccount.address });
|
|
@@ -329,23 +340,34 @@ var overrideContractActions = (client) => {
|
|
|
329
340
|
type: "legacy",
|
|
330
341
|
nonce
|
|
331
342
|
});
|
|
332
|
-
|
|
343
|
+
return await client.request({
|
|
333
344
|
method: "eth_sendRawTransaction",
|
|
334
345
|
params: [signedTransaction]
|
|
335
346
|
});
|
|
336
|
-
return result;
|
|
337
347
|
};
|
|
338
348
|
client.deployContract = async (args) => {
|
|
339
349
|
const { account, code, args: constructorArgs, leaderOnly = false } = args;
|
|
340
350
|
const data = [code, encode({ args: constructorArgs }), leaderOnly];
|
|
341
351
|
const serializedData = serialize(data);
|
|
342
352
|
const senderAccount = account || client.account;
|
|
353
|
+
if (_optionalChain([senderAccount, 'optionalAccess', _11 => _11.type]) !== "local") {
|
|
354
|
+
const transaction = {
|
|
355
|
+
from: _optionalChain([senderAccount, 'optionalAccess', _12 => _12.address]),
|
|
356
|
+
to: null,
|
|
357
|
+
data: serializedData,
|
|
358
|
+
value: "0x0"
|
|
359
|
+
};
|
|
360
|
+
return await client.request({
|
|
361
|
+
method: "eth_sendTransaction",
|
|
362
|
+
params: [transaction]
|
|
363
|
+
});
|
|
364
|
+
}
|
|
343
365
|
if (!senderAccount) {
|
|
344
366
|
throw new Error(
|
|
345
367
|
"No account set. Configure the client with an account or pass an account to this function."
|
|
346
368
|
);
|
|
347
369
|
}
|
|
348
|
-
if (!_optionalChain([senderAccount, 'optionalAccess',
|
|
370
|
+
if (!_optionalChain([senderAccount, 'optionalAccess', _13 => _13.signTransaction])) {
|
|
349
371
|
throw new Error("Account does not support signTransaction");
|
|
350
372
|
}
|
|
351
373
|
const nonce = await client.getCurrentNonce({ address: senderAccount.address });
|
|
@@ -354,11 +376,10 @@ var overrideContractActions = (client) => {
|
|
|
354
376
|
type: "legacy",
|
|
355
377
|
nonce
|
|
356
378
|
});
|
|
357
|
-
|
|
379
|
+
return await client.request({
|
|
358
380
|
method: "eth_sendRawTransaction",
|
|
359
381
|
params: [signedTransaction]
|
|
360
382
|
});
|
|
361
|
-
return result;
|
|
362
383
|
};
|
|
363
384
|
return client;
|
|
364
385
|
};
|
|
@@ -406,13 +427,48 @@ var transactionActions = (client) => ({
|
|
|
406
427
|
var createClient = (config = { chain: _chunkIINRDYKFcjs.simulator }) => {
|
|
407
428
|
const chainConfig = config.chain || _chunkIINRDYKFcjs.simulator;
|
|
408
429
|
const rpcUrl = config.endpoint || chainConfig.rpcUrls.default.http[0];
|
|
430
|
+
const isAddress = typeof config.account !== "object";
|
|
431
|
+
const customTransport = {
|
|
432
|
+
async request({ method, params }) {
|
|
433
|
+
if (method.startsWith("eth_") && isAddress) {
|
|
434
|
+
try {
|
|
435
|
+
return await _optionalChain([window, 'access', _14 => _14.ethereum, 'optionalAccess', _15 => _15.request, 'call', _16 => _16({ method, params })]);
|
|
436
|
+
} catch (err) {
|
|
437
|
+
console.warn(`Error using window.ethereum for method ${method}:`, err);
|
|
438
|
+
throw err;
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
try {
|
|
442
|
+
const response = await fetch(rpcUrl, {
|
|
443
|
+
method: "POST",
|
|
444
|
+
headers: {
|
|
445
|
+
"Content-Type": "application/json"
|
|
446
|
+
},
|
|
447
|
+
body: JSON.stringify({
|
|
448
|
+
jsonrpc: "2.0",
|
|
449
|
+
id: Date.now(),
|
|
450
|
+
method,
|
|
451
|
+
params
|
|
452
|
+
})
|
|
453
|
+
});
|
|
454
|
+
const data = await response.json();
|
|
455
|
+
if (data.error) {
|
|
456
|
+
throw new Error(data.error.message);
|
|
457
|
+
}
|
|
458
|
+
return data.result;
|
|
459
|
+
} catch (err) {
|
|
460
|
+
console.error(`Error fetching ${method} from GenLayer RPC:`, err);
|
|
461
|
+
throw err;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
};
|
|
409
466
|
const baseClient = _viem.createClient.call(void 0, {
|
|
410
467
|
chain: chainConfig,
|
|
411
|
-
transport: _viem.
|
|
468
|
+
transport: _viem.custom.call(void 0, customTransport),
|
|
412
469
|
...config.account ? { account: config.account } : {}
|
|
413
470
|
}).extend(_viem.publicActions).extend((client) => accountActions(client)).extend((client) => transactionActions(client)).extend((client) => contractActions(client));
|
|
414
|
-
|
|
415
|
-
return genLayerClient;
|
|
471
|
+
return overrideContractActions(baseClient);
|
|
416
472
|
};
|
|
417
473
|
|
|
418
474
|
// src/accounts/account.ts
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as viem from 'viem';
|
|
2
|
-
import { Account } from 'viem';
|
|
2
|
+
import { Account, Address } from 'viem';
|
|
3
3
|
import { S as SimulatorChain } from './chains-BV4Glo-M.cjs';
|
|
4
4
|
import { GenLayerClient } from './types/index.cjs';
|
|
5
5
|
import * as abitype from 'abitype';
|
|
@@ -29,7 +29,7 @@ interface ClientConfig {
|
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
31
|
endpoint?: string;
|
|
32
|
-
account?: Account;
|
|
32
|
+
account?: Account | Address;
|
|
33
33
|
}
|
|
34
34
|
declare const createClient: (config?: ClientConfig) => GenLayerClient<SimulatorChain>;
|
|
35
35
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as viem from 'viem';
|
|
2
|
-
import { Account } from 'viem';
|
|
2
|
+
import { Account, Address } from 'viem';
|
|
3
3
|
import { S as SimulatorChain } from './chains-BV4Glo-M.js';
|
|
4
4
|
import { GenLayerClient } from './types/index.js';
|
|
5
5
|
import * as abitype from 'abitype';
|
|
@@ -29,7 +29,7 @@ interface ClientConfig {
|
|
|
29
29
|
};
|
|
30
30
|
};
|
|
31
31
|
endpoint?: string;
|
|
32
|
-
account?: Account;
|
|
32
|
+
account?: Account | Address;
|
|
33
33
|
}
|
|
34
34
|
declare const createClient: (config?: ClientConfig) => GenLayerClient<SimulatorChain>;
|
|
35
35
|
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
} from "./chunk-3TYB36DW.js";
|
|
5
5
|
import {
|
|
6
6
|
Address
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-G7EQ6KPE.js";
|
|
8
8
|
import "./chunk-MLKGABMK.js";
|
|
9
9
|
|
|
10
10
|
// src/client/client.ts
|
|
11
|
-
import { createClient as createViemClient,
|
|
11
|
+
import { createClient as createViemClient, publicActions, custom } from "viem";
|
|
12
12
|
|
|
13
13
|
// src/accounts/actions.ts
|
|
14
14
|
function accountActions(client) {
|
|
@@ -22,14 +22,14 @@ function accountActions(client) {
|
|
|
22
22
|
params: [address, amount]
|
|
23
23
|
});
|
|
24
24
|
},
|
|
25
|
-
getCurrentNonce: async ({ address }) => {
|
|
25
|
+
getCurrentNonce: async ({ address, block = "latest" }) => {
|
|
26
26
|
const addressToUse = address || client.account?.address;
|
|
27
27
|
if (!addressToUse) {
|
|
28
28
|
throw new Error("No address provided and no account is connected");
|
|
29
29
|
}
|
|
30
30
|
return client.request({
|
|
31
31
|
method: "eth_getTransactionCount",
|
|
32
|
-
params: [addressToUse]
|
|
32
|
+
params: [addressToUse, block]
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
};
|
|
@@ -265,9 +265,6 @@ function encode(data) {
|
|
|
265
265
|
function serialize(data) {
|
|
266
266
|
return toRlp(data.map((param) => toHex(param)));
|
|
267
267
|
}
|
|
268
|
-
function encodeAndSerialize(data) {
|
|
269
|
-
return serialize([encode(data)]);
|
|
270
|
-
}
|
|
271
268
|
|
|
272
269
|
// src/contracts/actions.ts
|
|
273
270
|
var contractActions = (client) => {
|
|
@@ -290,12 +287,14 @@ var contractActions = (client) => {
|
|
|
290
287
|
};
|
|
291
288
|
var overrideContractActions = (client) => {
|
|
292
289
|
client.readContract = async (args) => {
|
|
293
|
-
const { account, address, functionName, args: params } = args;
|
|
294
|
-
const encodedData =
|
|
290
|
+
const { account, address, functionName, args: params, stateStatus = "ACCEPTED" /* ACCEPTED */ } = args;
|
|
291
|
+
const encodedData = [encode({ method: functionName, args: params }), stateStatus];
|
|
292
|
+
const serializedData = serialize(encodedData);
|
|
293
|
+
const senderAddress = account?.address ?? client.account?.address;
|
|
295
294
|
const requestParams = {
|
|
296
295
|
to: address,
|
|
297
|
-
from:
|
|
298
|
-
data:
|
|
296
|
+
from: senderAddress,
|
|
297
|
+
data: serializedData
|
|
299
298
|
};
|
|
300
299
|
const result = await client.request({
|
|
301
300
|
method: "eth_call",
|
|
@@ -313,6 +312,18 @@ var overrideContractActions = (client) => {
|
|
|
313
312
|
const data = [encode({ method: functionName, args: params }), leaderOnly];
|
|
314
313
|
const serializedData = serialize(data);
|
|
315
314
|
const senderAccount = account || client.account;
|
|
315
|
+
if (senderAccount?.type !== "local") {
|
|
316
|
+
const transaction = {
|
|
317
|
+
from: senderAccount?.address,
|
|
318
|
+
to: address,
|
|
319
|
+
data: serializedData,
|
|
320
|
+
value: `0x${value.toString(16)}`
|
|
321
|
+
};
|
|
322
|
+
return await client.request({
|
|
323
|
+
method: "eth_sendTransaction",
|
|
324
|
+
params: [transaction]
|
|
325
|
+
});
|
|
326
|
+
}
|
|
316
327
|
if (!senderAccount) {
|
|
317
328
|
throw new Error(
|
|
318
329
|
"No account set. Configure the client with an account or pass an account to this function."
|
|
@@ -329,17 +340,28 @@ var overrideContractActions = (client) => {
|
|
|
329
340
|
type: "legacy",
|
|
330
341
|
nonce
|
|
331
342
|
});
|
|
332
|
-
|
|
343
|
+
return await client.request({
|
|
333
344
|
method: "eth_sendRawTransaction",
|
|
334
345
|
params: [signedTransaction]
|
|
335
346
|
});
|
|
336
|
-
return result;
|
|
337
347
|
};
|
|
338
348
|
client.deployContract = async (args) => {
|
|
339
349
|
const { account, code, args: constructorArgs, leaderOnly = false } = args;
|
|
340
350
|
const data = [code, encode({ args: constructorArgs }), leaderOnly];
|
|
341
351
|
const serializedData = serialize(data);
|
|
342
352
|
const senderAccount = account || client.account;
|
|
353
|
+
if (senderAccount?.type !== "local") {
|
|
354
|
+
const transaction = {
|
|
355
|
+
from: senderAccount?.address,
|
|
356
|
+
to: null,
|
|
357
|
+
data: serializedData,
|
|
358
|
+
value: "0x0"
|
|
359
|
+
};
|
|
360
|
+
return await client.request({
|
|
361
|
+
method: "eth_sendTransaction",
|
|
362
|
+
params: [transaction]
|
|
363
|
+
});
|
|
364
|
+
}
|
|
343
365
|
if (!senderAccount) {
|
|
344
366
|
throw new Error(
|
|
345
367
|
"No account set. Configure the client with an account or pass an account to this function."
|
|
@@ -354,11 +376,10 @@ var overrideContractActions = (client) => {
|
|
|
354
376
|
type: "legacy",
|
|
355
377
|
nonce
|
|
356
378
|
});
|
|
357
|
-
|
|
379
|
+
return await client.request({
|
|
358
380
|
method: "eth_sendRawTransaction",
|
|
359
381
|
params: [signedTransaction]
|
|
360
382
|
});
|
|
361
|
-
return result;
|
|
362
383
|
};
|
|
363
384
|
return client;
|
|
364
385
|
};
|
|
@@ -406,13 +427,48 @@ var transactionActions = (client) => ({
|
|
|
406
427
|
var createClient = (config = { chain: simulator }) => {
|
|
407
428
|
const chainConfig = config.chain || simulator;
|
|
408
429
|
const rpcUrl = config.endpoint || chainConfig.rpcUrls.default.http[0];
|
|
430
|
+
const isAddress = typeof config.account !== "object";
|
|
431
|
+
const customTransport = {
|
|
432
|
+
async request({ method, params }) {
|
|
433
|
+
if (method.startsWith("eth_") && isAddress) {
|
|
434
|
+
try {
|
|
435
|
+
return await window.ethereum?.request({ method, params });
|
|
436
|
+
} catch (err) {
|
|
437
|
+
console.warn(`Error using window.ethereum for method ${method}:`, err);
|
|
438
|
+
throw err;
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
try {
|
|
442
|
+
const response = await fetch(rpcUrl, {
|
|
443
|
+
method: "POST",
|
|
444
|
+
headers: {
|
|
445
|
+
"Content-Type": "application/json"
|
|
446
|
+
},
|
|
447
|
+
body: JSON.stringify({
|
|
448
|
+
jsonrpc: "2.0",
|
|
449
|
+
id: Date.now(),
|
|
450
|
+
method,
|
|
451
|
+
params
|
|
452
|
+
})
|
|
453
|
+
});
|
|
454
|
+
const data = await response.json();
|
|
455
|
+
if (data.error) {
|
|
456
|
+
throw new Error(data.error.message);
|
|
457
|
+
}
|
|
458
|
+
return data.result;
|
|
459
|
+
} catch (err) {
|
|
460
|
+
console.error(`Error fetching ${method} from GenLayer RPC:`, err);
|
|
461
|
+
throw err;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
};
|
|
409
466
|
const baseClient = createViemClient({
|
|
410
467
|
chain: chainConfig,
|
|
411
|
-
transport:
|
|
468
|
+
transport: custom(customTransport),
|
|
412
469
|
...config.account ? { account: config.account } : {}
|
|
413
470
|
}).extend(publicActions).extend((client) => accountActions(client)).extend((client) => transactionActions(client)).extend((client) => contractActions(client));
|
|
414
|
-
|
|
415
|
-
return genLayerClient;
|
|
471
|
+
return overrideContractActions(baseClient);
|
|
416
472
|
};
|
|
417
473
|
|
|
418
474
|
// src/accounts/account.ts
|
package/dist/types/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkX6WK4DK4cjs = require('../chunk-X6WK4DK4.cjs');
|
|
4
4
|
require('../chunk-75ZPJI57.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
exports.TransactionStatus =
|
|
7
|
+
exports.TransactionStatus = _chunkX6WK4DK4cjs.TransactionStatus;
|
package/dist/types/index.d.cts
CHANGED
|
@@ -118,7 +118,7 @@ type GenLayerMethod = {
|
|
|
118
118
|
params: [address: string, filter?: "all" | "from" | "to"];
|
|
119
119
|
} | {
|
|
120
120
|
method: "eth_getTransactionCount";
|
|
121
|
-
params: [address: string];
|
|
121
|
+
params: [address: string, block: string];
|
|
122
122
|
};
|
|
123
123
|
type GenLayerClient<TSimulatorChain extends SimulatorChain> = Omit<Client<Transport, TSimulatorChain>, "transport" | "getTransaction" | "readContract"> & Omit<PublicActions<Transport, TSimulatorChain>, "readContract" | "getTransaction" | "waitForTransactionReceipt"> & {
|
|
124
124
|
request: Client<Transport, TSimulatorChain>["request"] & {
|
|
@@ -131,6 +131,7 @@ type GenLayerClient<TSimulatorChain extends SimulatorChain> = Omit<Client<Transp
|
|
|
131
131
|
address: Address$1;
|
|
132
132
|
functionName: string;
|
|
133
133
|
args: CalldataEncodable[];
|
|
134
|
+
stateStatus?: TransactionStatus;
|
|
134
135
|
}) => Promise<unknown>;
|
|
135
136
|
writeContract: (args: {
|
|
136
137
|
account?: Account;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -118,7 +118,7 @@ type GenLayerMethod = {
|
|
|
118
118
|
params: [address: string, filter?: "all" | "from" | "to"];
|
|
119
119
|
} | {
|
|
120
120
|
method: "eth_getTransactionCount";
|
|
121
|
-
params: [address: string];
|
|
121
|
+
params: [address: string, block: string];
|
|
122
122
|
};
|
|
123
123
|
type GenLayerClient<TSimulatorChain extends SimulatorChain> = Omit<Client<Transport, TSimulatorChain>, "transport" | "getTransaction" | "readContract"> & Omit<PublicActions<Transport, TSimulatorChain>, "readContract" | "getTransaction" | "waitForTransactionReceipt"> & {
|
|
124
124
|
request: Client<Transport, TSimulatorChain>["request"] & {
|
|
@@ -131,6 +131,7 @@ type GenLayerClient<TSimulatorChain extends SimulatorChain> = Omit<Client<Transp
|
|
|
131
131
|
address: Address$1;
|
|
132
132
|
functionName: string;
|
|
133
133
|
args: CalldataEncodable[];
|
|
134
|
+
stateStatus?: TransactionStatus;
|
|
134
135
|
}) => Promise<unknown>;
|
|
135
136
|
writeContract: (args: {
|
|
136
137
|
account?: Account;
|
package/dist/types/index.js
CHANGED
package/package.json
CHANGED
package/src/accounts/actions.ts
CHANGED
|
@@ -13,16 +13,15 @@ export function accountActions(client: GenLayerClient<SimulatorChain>) {
|
|
|
13
13
|
params: [address, amount],
|
|
14
14
|
}) as Promise<TransactionHash>;
|
|
15
15
|
},
|
|
16
|
-
getCurrentNonce: async ({address}: {address: string}): Promise<number> => {
|
|
16
|
+
getCurrentNonce: async ({address, block = 'latest'}: {address: string, block?: string}): Promise<number> => {
|
|
17
17
|
const addressToUse = address || client.account?.address;
|
|
18
18
|
|
|
19
19
|
if (!addressToUse) {
|
|
20
20
|
throw new Error("No address provided and no account is connected");
|
|
21
21
|
}
|
|
22
|
-
|
|
23
22
|
return client.request({
|
|
24
23
|
method: "eth_getTransactionCount",
|
|
25
|
-
params: [addressToUse],
|
|
24
|
+
params: [addressToUse, block],
|
|
26
25
|
}) as Promise<number>;
|
|
27
26
|
},
|
|
28
27
|
};
|
package/src/client/client.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Account, createClient as createViemClient,
|
|
1
|
+
import {Account, createClient as createViemClient, publicActions, custom, Address} from "viem";
|
|
2
2
|
import {simulator} from "../chains/simulator";
|
|
3
3
|
import {accountActions} from "../accounts/actions";
|
|
4
4
|
import {contractActions, overrideContractActions} from "../contracts/actions";
|
|
@@ -10,24 +10,62 @@ interface ClientConfig {
|
|
|
10
10
|
chain?: {
|
|
11
11
|
id: number;
|
|
12
12
|
name: string;
|
|
13
|
-
rpcUrls: {default: {http: readonly string[]}};
|
|
14
|
-
nativeCurrency: {name: string; symbol: string; decimals: number};
|
|
15
|
-
blockExplorers?: {default: {name: string; url: string}};
|
|
13
|
+
rpcUrls: { default: { http: readonly string[] } };
|
|
14
|
+
nativeCurrency: { name: string; symbol: string; decimals: number };
|
|
15
|
+
blockExplorers?: { default: { name: string; url: string } };
|
|
16
16
|
};
|
|
17
|
-
endpoint?: string; //
|
|
18
|
-
account?: Account;
|
|
17
|
+
endpoint?: string; // Custom RPC endpoint
|
|
18
|
+
account?: Account | Address;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
export const createClient = (config: ClientConfig = {chain: simulator}) => {
|
|
23
|
-
// Determine the RPC URL based on the provided configuration or default to the simulator's RPC UR
|
|
21
|
+
export const createClient = (config: ClientConfig = { chain: simulator }) => {
|
|
24
22
|
const chainConfig = config.chain || simulator;
|
|
25
23
|
const rpcUrl = config.endpoint || chainConfig.rpcUrls.default.http[0];
|
|
24
|
+
const isAddress = typeof config.account !== "object";
|
|
25
|
+
|
|
26
|
+
const customTransport = {
|
|
27
|
+
async request({method, params}: {method: string; params: any[]}) {
|
|
28
|
+
if (method.startsWith('eth_') && isAddress) {
|
|
29
|
+
try {
|
|
30
|
+
return await window.ethereum?.request({method, params});
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.warn(`Error using window.ethereum for method ${method}:`, err);
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
} else {
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetch(rpcUrl, {
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: {
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
},
|
|
42
|
+
body: JSON.stringify({
|
|
43
|
+
jsonrpc: '2.0',
|
|
44
|
+
id: Date.now(),
|
|
45
|
+
method,
|
|
46
|
+
params,
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const data = await response.json();
|
|
51
|
+
|
|
52
|
+
if (data.error) {
|
|
53
|
+
throw new Error(data.error.message);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return data.result;
|
|
57
|
+
} catch (err) {
|
|
58
|
+
console.error(`Error fetching ${method} from GenLayer RPC:`, err);
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
}
|
|
64
|
+
|
|
26
65
|
|
|
27
|
-
// Create a Viem client connected to the GenLayer Simulator (or custom chain)
|
|
28
66
|
const baseClient = createViemClient({
|
|
29
67
|
chain: chainConfig,
|
|
30
|
-
transport:
|
|
68
|
+
transport: custom(customTransport),
|
|
31
69
|
...(config.account ? {account: config.account} : {}),
|
|
32
70
|
})
|
|
33
71
|
.extend(publicActions)
|
|
@@ -35,7 +73,7 @@ export const createClient = (config: ClientConfig = {chain: simulator}) => {
|
|
|
35
73
|
.extend(client => transactionActions(client as unknown as GenLayerClient<SimulatorChain>))
|
|
36
74
|
.extend(client => contractActions(client as unknown as GenLayerClient<SimulatorChain>));
|
|
37
75
|
|
|
38
|
-
|
|
76
|
+
return overrideContractActions(baseClient as unknown as GenLayerClient<SimulatorChain>);
|
|
39
77
|
|
|
40
|
-
return genLayerClient;
|
|
41
78
|
};
|
|
79
|
+
|
package/src/contracts/actions.ts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import {decode} from "@/abi/calldata/decoder";
|
|
2
|
-
import {encode, serialize
|
|
3
|
-
import {
|
|
2
|
+
import {encode, serialize} from "@/abi/calldata/encoder";
|
|
3
|
+
import {
|
|
4
|
+
Account,
|
|
5
|
+
ContractSchema,
|
|
6
|
+
SimulatorChain,
|
|
7
|
+
GenLayerClient,
|
|
8
|
+
CalldataEncodable,
|
|
9
|
+
Address,
|
|
10
|
+
TransactionStatus,
|
|
11
|
+
} from "@/types";
|
|
4
12
|
|
|
5
13
|
export const contractActions = (client: GenLayerClient<SimulatorChain>) => {
|
|
6
14
|
return {
|
|
@@ -27,14 +35,18 @@ export const overrideContractActions = (client: GenLayerClient<SimulatorChain>)
|
|
|
27
35
|
address: Address;
|
|
28
36
|
functionName: string;
|
|
29
37
|
args: CalldataEncodable[];
|
|
38
|
+
stateStatus?: TransactionStatus;
|
|
30
39
|
}): Promise<unknown> => {
|
|
31
|
-
const {account, address, functionName, args: params} = args;
|
|
32
|
-
const encodedData =
|
|
40
|
+
const {account, address, functionName, args: params, stateStatus = TransactionStatus.ACCEPTED} = args;
|
|
41
|
+
const encodedData = [encode({method: functionName, args: params}), stateStatus];
|
|
42
|
+
const serializedData = serialize(encodedData);
|
|
43
|
+
|
|
44
|
+
const senderAddress = account?.address ?? client.account?.address;
|
|
33
45
|
|
|
34
46
|
const requestParams = {
|
|
35
47
|
to: address,
|
|
36
|
-
from:
|
|
37
|
-
data:
|
|
48
|
+
from: senderAddress,
|
|
49
|
+
data: serializedData,
|
|
38
50
|
};
|
|
39
51
|
const result = await client.request({
|
|
40
52
|
method: "eth_call",
|
|
@@ -60,8 +72,22 @@ export const overrideContractActions = (client: GenLayerClient<SimulatorChain>)
|
|
|
60
72
|
const {account, address, functionName, args: params, value = 0n, leaderOnly = false} = args;
|
|
61
73
|
const data = [encode({method: functionName, args: params}), leaderOnly];
|
|
62
74
|
const serializedData = serialize(data);
|
|
63
|
-
|
|
64
75
|
const senderAccount = account || client.account;
|
|
76
|
+
|
|
77
|
+
if (senderAccount?.type !== "local") {
|
|
78
|
+
const transaction = {
|
|
79
|
+
from: senderAccount?.address,
|
|
80
|
+
to: address,
|
|
81
|
+
data: serializedData,
|
|
82
|
+
value: `0x${value.toString(16)}`,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
return await client.request({
|
|
86
|
+
method: "eth_sendTransaction",
|
|
87
|
+
params: [transaction as any],
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
65
91
|
if (!senderAccount) {
|
|
66
92
|
throw new Error(
|
|
67
93
|
"No account set. Configure the client with an account or pass an account to this function.",
|
|
@@ -81,11 +107,11 @@ export const overrideContractActions = (client: GenLayerClient<SimulatorChain>)
|
|
|
81
107
|
type: "legacy",
|
|
82
108
|
nonce,
|
|
83
109
|
});
|
|
84
|
-
|
|
110
|
+
|
|
111
|
+
return await client.request({
|
|
85
112
|
method: "eth_sendRawTransaction",
|
|
86
113
|
params: [signedTransaction],
|
|
87
114
|
});
|
|
88
|
-
return result;
|
|
89
115
|
};
|
|
90
116
|
|
|
91
117
|
client.deployContract = async (args: {
|
|
@@ -97,8 +123,22 @@ export const overrideContractActions = (client: GenLayerClient<SimulatorChain>)
|
|
|
97
123
|
const {account, code, args: constructorArgs, leaderOnly = false} = args;
|
|
98
124
|
const data = [code, encode({args: constructorArgs}), leaderOnly];
|
|
99
125
|
const serializedData = serialize(data);
|
|
100
|
-
|
|
101
126
|
const senderAccount = account || client.account;
|
|
127
|
+
|
|
128
|
+
if (senderAccount?.type !== "local") {
|
|
129
|
+
const transaction = {
|
|
130
|
+
from: senderAccount?.address,
|
|
131
|
+
to: null,
|
|
132
|
+
data: serializedData,
|
|
133
|
+
value: "0x0",
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
return await client.request({
|
|
137
|
+
method: "eth_sendTransaction",
|
|
138
|
+
params: [transaction as any],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
102
142
|
if (!senderAccount) {
|
|
103
143
|
throw new Error(
|
|
104
144
|
"No account set. Configure the client with an account or pass an account to this function.",
|
|
@@ -117,11 +157,10 @@ export const overrideContractActions = (client: GenLayerClient<SimulatorChain>)
|
|
|
117
157
|
nonce,
|
|
118
158
|
});
|
|
119
159
|
|
|
120
|
-
|
|
160
|
+
return await client.request({
|
|
121
161
|
method: "eth_sendRawTransaction",
|
|
122
162
|
params: [signedTransaction],
|
|
123
163
|
});
|
|
124
|
-
return result;
|
|
125
164
|
};
|
|
126
165
|
|
|
127
166
|
return client;
|
package/src/global.d.ts
ADDED
package/src/types/clients.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type GenLayerMethod =
|
|
|
13
13
|
| {method: "gen_getContractSchema"; params: [address: string]}
|
|
14
14
|
| {method: "gen_getContractSchemaForCode"; params: [contractCode: string]}
|
|
15
15
|
| {method: "sim_getTransactionsForAddress"; params: [address: string, filter?: "all" | "from" | "to"]}
|
|
16
|
-
| {method: "eth_getTransactionCount"; params: [address: string]};
|
|
16
|
+
| {method: "eth_getTransactionCount"; params: [address: string, block: string]};
|
|
17
17
|
|
|
18
18
|
/*
|
|
19
19
|
Take all the properties from PublicActions<Transport, TSimulatorChain>
|
|
@@ -39,6 +39,7 @@ export type GenLayerClient<TSimulatorChain extends SimulatorChain> = Omit<
|
|
|
39
39
|
address: Address;
|
|
40
40
|
functionName: string;
|
|
41
41
|
args: CalldataEncodable[];
|
|
42
|
+
stateStatus?: TransactionStatus;
|
|
42
43
|
}) => Promise<unknown>;
|
|
43
44
|
writeContract: (args: {
|
|
44
45
|
account?: Account;
|
package/tests/client.test.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {simulator} from "../src/chains/simulator";
|
|
|
4
4
|
import {Address} from "../src/types/accounts";
|
|
5
5
|
import {createAccount, generatePrivateKey} from "../src/accounts/account";
|
|
6
6
|
import {vi} from "vitest";
|
|
7
|
+
import {TransactionStatus} from "../src/types/transactions";
|
|
7
8
|
|
|
8
9
|
describe("Client Creation", () => {
|
|
9
10
|
it("should create a client for the simulator", () => {
|
|
@@ -18,7 +19,7 @@ describe("Client Overrides", () => {
|
|
|
18
19
|
const account = createAccount(generatePrivateKey());
|
|
19
20
|
const client = createClient({
|
|
20
21
|
chain: simulator,
|
|
21
|
-
account,
|
|
22
|
+
account: account,
|
|
22
23
|
});
|
|
23
24
|
|
|
24
25
|
// Mock the client.request method
|
|
@@ -29,6 +30,7 @@ describe("Client Overrides", () => {
|
|
|
29
30
|
address: contractAddress as Address,
|
|
30
31
|
functionName: "testFunction",
|
|
31
32
|
args: ["arg1", "arg2"],
|
|
33
|
+
stateStatus: TransactionStatus.ACCEPTED,
|
|
32
34
|
});
|
|
33
35
|
|
|
34
36
|
expect(client.request).toHaveBeenCalledWith({
|
|
@@ -62,6 +64,7 @@ describe("Client Overrides", () => {
|
|
|
62
64
|
address: contractAddress as Address,
|
|
63
65
|
functionName: "testFunction",
|
|
64
66
|
args: ["arg1", "arg2"],
|
|
67
|
+
stateStatus: TransactionStatus.ACCEPTED,
|
|
65
68
|
});
|
|
66
69
|
|
|
67
70
|
expect(client.request).toHaveBeenCalledWith({
|
|
@@ -76,4 +79,33 @@ describe("Client Overrides", () => {
|
|
|
76
79
|
],
|
|
77
80
|
});
|
|
78
81
|
});
|
|
82
|
+
it("should override client account if address is provided", async () => {
|
|
83
|
+
const account = "0x65e03a3e916CF1dC92d3C8E8186a89CfAB0D2bc2";
|
|
84
|
+
const client = createClient({
|
|
85
|
+
chain: simulator,
|
|
86
|
+
account,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// Mock the client.request method
|
|
90
|
+
vi.spyOn(client, "request").mockResolvedValue(undefined);
|
|
91
|
+
|
|
92
|
+
const contractAddress = "0x1234567890123456789012345678901234567890";
|
|
93
|
+
await client.readContract({
|
|
94
|
+
address: contractAddress as Address,
|
|
95
|
+
functionName: "testFunction",
|
|
96
|
+
args: ["arg1", "arg2"],
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
expect(client.request).toHaveBeenCalledWith({
|
|
100
|
+
method: "eth_call",
|
|
101
|
+
params: [
|
|
102
|
+
{
|
|
103
|
+
to: contractAddress,
|
|
104
|
+
from: account,
|
|
105
|
+
data: expect.any(String),
|
|
106
|
+
},
|
|
107
|
+
"latest",
|
|
108
|
+
],
|
|
109
|
+
});
|
|
110
|
+
});
|
|
79
111
|
});
|
package/tsconfig.json
CHANGED
|
@@ -115,5 +115,5 @@
|
|
|
115
115
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
116
116
|
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
|
117
117
|
},
|
|
118
|
-
"include": ["src/**/*", "tests/**/*"]
|
|
118
|
+
"include": ["src/**/*", "tests/**/*", "src/global.d.ts"]
|
|
119
119
|
}
|
|
File without changes
|
|
File without changes
|