genlayer-js 0.1.2 → 0.3.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/dist/{chunk-VQTD5PMI.js → chunk-M7SA3INM.js} +12 -0
- package/dist/{chunk-AR7OM4HI.cjs → chunk-YI62SDKV.cjs} +14 -2
- package/dist/{clients-CL75M8Ma.d.cts → clients-BamlAEcy.d.cts} +32 -4
- package/dist/{clients-Bt_8fb_v.d.ts → clients-CJ820ePR.d.ts} +32 -4
- package/dist/index.cjs +193 -11
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +191 -9
- package/dist/types/index.cjs +2 -2
- package/dist/types/index.d.cts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.js +1 -1
- package/package.json +2 -1
- package/src/abi/calldata/encoder.ts +168 -0
- package/src/abi/index.ts +2 -0
- package/src/accounts/actions.ts +6 -0
- package/src/contracts/actions.ts +41 -11
- package/src/types/calldata.ts +38 -0
- package/src/types/clients.ts +5 -1
- package/src/types/index.ts +1 -0
- package/src/types/transactions.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
+
## 0.3.0 (2024-10-25)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* add deploy contract action ([#17](https://github.com/yeagerai/genlayer-js/issues/17)) ([23d5bc2](https://github.com/yeagerai/genlayer-js/commit/23d5bc28fb58c73d64b1fd629185a0565d84cb91))
|
|
9
|
+
|
|
10
|
+
## 0.2.0 (2024-10-17)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* implement genvm calldata ([#14](https://github.com/yeagerai/genlayer-js/issues/14)) ([d9a1abd](https://github.com/yeagerai/genlayer-js/commit/d9a1abdfb5eef13e5c77433db546953369087e04))
|
|
16
|
+
|
|
3
17
|
## 0.1.2 (2024-10-03)
|
|
4
18
|
|
|
5
19
|
## 0.1.1 (2024-10-03)
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
// src/types/calldata.ts
|
|
2
|
+
var Address = class {
|
|
3
|
+
bytes;
|
|
4
|
+
constructor(addr) {
|
|
5
|
+
if (addr.length != 32) {
|
|
6
|
+
throw new Error(`invalid address length ${addr}`);
|
|
7
|
+
}
|
|
8
|
+
this.bytes = addr;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
1
12
|
// src/types/transactions.ts
|
|
2
13
|
var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
|
|
3
14
|
TransactionStatus2["PENDING"] = "PENDING";
|
|
@@ -12,5 +23,6 @@ var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
|
|
|
12
23
|
})(TransactionStatus || {});
|
|
13
24
|
|
|
14
25
|
export {
|
|
26
|
+
Address,
|
|
15
27
|
TransactionStatus
|
|
16
28
|
};
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/types/
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/types/calldata.ts
|
|
2
|
+
var Address = class {
|
|
3
|
+
|
|
4
|
+
constructor(addr) {
|
|
5
|
+
if (addr.length != 32) {
|
|
6
|
+
throw new Error(`invalid address length ${addr}`);
|
|
7
|
+
}
|
|
8
|
+
this.bytes = addr;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
// src/types/transactions.ts
|
|
2
13
|
var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
|
|
3
14
|
TransactionStatus2["PENDING"] = "PENDING";
|
|
4
15
|
TransactionStatus2["CANCELED"] = "CANCELED";
|
|
@@ -13,4 +24,5 @@ var TransactionStatus = /* @__PURE__ */ ((TransactionStatus2) => {
|
|
|
13
24
|
|
|
14
25
|
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
|
|
28
|
+
exports.Address = Address; exports.TransactionStatus = TransactionStatus;
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import { Transport, Account, Client } from 'viem';
|
|
2
2
|
import { S as SimulatorChain } from './chains-CtZJFz4Q.cjs';
|
|
3
3
|
|
|
4
|
-
type Address = `0x${string}` & {
|
|
4
|
+
type Address$1 = `0x${string}` & {
|
|
5
5
|
length: 42;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
declare class Address {
|
|
9
|
+
bytes: Uint8Array;
|
|
10
|
+
constructor(addr: Uint8Array);
|
|
11
|
+
}
|
|
12
|
+
type CalldataEncodable = null | boolean | Address | number | bigint | string | Uint8Array | Address | Array<CalldataEncodable> | Map<string, CalldataEncodable> | {
|
|
13
|
+
[key: string]: CalldataEncodable;
|
|
14
|
+
};
|
|
15
|
+
type MethodDescription = {
|
|
16
|
+
method: string;
|
|
17
|
+
args: Array<CalldataEncodable>;
|
|
18
|
+
};
|
|
19
|
+
type TransactionData = {
|
|
20
|
+
method: string;
|
|
21
|
+
args: CalldataEncodable[];
|
|
22
|
+
};
|
|
23
|
+
|
|
8
24
|
type TransactionHash = `0x${string}` & {
|
|
9
25
|
length: 66;
|
|
10
26
|
};
|
|
@@ -34,6 +50,7 @@ type GenLayerTransaction = {
|
|
|
34
50
|
s?: number;
|
|
35
51
|
v?: number;
|
|
36
52
|
};
|
|
53
|
+
type TransactionDataElement = string | number | bigint | boolean | Uint8Array;
|
|
37
54
|
|
|
38
55
|
type GenLayerMethod = {
|
|
39
56
|
method: "sim_fundAccount";
|
|
@@ -53,6 +70,9 @@ type GenLayerMethod = {
|
|
|
53
70
|
} | {
|
|
54
71
|
method: "gen_getContractSchemaForCode";
|
|
55
72
|
params: [contractCode: string];
|
|
73
|
+
} | {
|
|
74
|
+
method: "eth_getTransactionCount";
|
|
75
|
+
params: [address: string];
|
|
56
76
|
};
|
|
57
77
|
type GenLayerClient<TTransport extends Transport, TSimulatorChain extends SimulatorChain, TAccount extends Account> = Client<TTransport, TSimulatorChain, TAccount> & {
|
|
58
78
|
request: Client<TTransport, TSimulatorChain, TAccount>["request"] & {
|
|
@@ -62,20 +82,28 @@ type GenLayerClient<TTransport extends Transport, TSimulatorChain extends Simula
|
|
|
62
82
|
};
|
|
63
83
|
readContract: (args: {
|
|
64
84
|
account: Account;
|
|
65
|
-
address: Address;
|
|
85
|
+
address: Address$1;
|
|
66
86
|
functionName: string;
|
|
67
87
|
args: any[];
|
|
68
88
|
}) => Promise<any>;
|
|
69
89
|
writeContract: (args: {
|
|
70
90
|
account: Account;
|
|
71
|
-
address: Address;
|
|
91
|
+
address: Address$1;
|
|
72
92
|
functionName: string;
|
|
73
93
|
args: any[];
|
|
74
94
|
value: bigint;
|
|
75
95
|
}) => Promise<any>;
|
|
96
|
+
deployContract: (args: {
|
|
97
|
+
account: Account;
|
|
98
|
+
code: string;
|
|
99
|
+
args: CalldataEncodable[];
|
|
100
|
+
}) => Promise<any>;
|
|
76
101
|
getTransaction: (args: {
|
|
77
102
|
hash: TransactionHash;
|
|
78
103
|
}) => Promise<GenLayerTransaction>;
|
|
104
|
+
getCurrentNonce: (args: {
|
|
105
|
+
address: string;
|
|
106
|
+
}) => Promise<number>;
|
|
79
107
|
};
|
|
80
108
|
|
|
81
|
-
export { type Address as A, type GenLayerClient as G, type
|
|
109
|
+
export { type Address$1 as A, type CalldataEncodable as C, type GenLayerClient as G, type MethodDescription as M, type TransactionData as T, type GenLayerMethod as a, type TransactionHash as b, TransactionStatus as c, type GenLayerTransaction as d, type TransactionDataElement as e };
|
|
@@ -1,10 +1,26 @@
|
|
|
1
1
|
import { Transport, Account, Client } from 'viem';
|
|
2
2
|
import { S as SimulatorChain } from './chains-CtZJFz4Q.js';
|
|
3
3
|
|
|
4
|
-
type Address = `0x${string}` & {
|
|
4
|
+
type Address$1 = `0x${string}` & {
|
|
5
5
|
length: 42;
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
declare class Address {
|
|
9
|
+
bytes: Uint8Array;
|
|
10
|
+
constructor(addr: Uint8Array);
|
|
11
|
+
}
|
|
12
|
+
type CalldataEncodable = null | boolean | Address | number | bigint | string | Uint8Array | Address | Array<CalldataEncodable> | Map<string, CalldataEncodable> | {
|
|
13
|
+
[key: string]: CalldataEncodable;
|
|
14
|
+
};
|
|
15
|
+
type MethodDescription = {
|
|
16
|
+
method: string;
|
|
17
|
+
args: Array<CalldataEncodable>;
|
|
18
|
+
};
|
|
19
|
+
type TransactionData = {
|
|
20
|
+
method: string;
|
|
21
|
+
args: CalldataEncodable[];
|
|
22
|
+
};
|
|
23
|
+
|
|
8
24
|
type TransactionHash = `0x${string}` & {
|
|
9
25
|
length: 66;
|
|
10
26
|
};
|
|
@@ -34,6 +50,7 @@ type GenLayerTransaction = {
|
|
|
34
50
|
s?: number;
|
|
35
51
|
v?: number;
|
|
36
52
|
};
|
|
53
|
+
type TransactionDataElement = string | number | bigint | boolean | Uint8Array;
|
|
37
54
|
|
|
38
55
|
type GenLayerMethod = {
|
|
39
56
|
method: "sim_fundAccount";
|
|
@@ -53,6 +70,9 @@ type GenLayerMethod = {
|
|
|
53
70
|
} | {
|
|
54
71
|
method: "gen_getContractSchemaForCode";
|
|
55
72
|
params: [contractCode: string];
|
|
73
|
+
} | {
|
|
74
|
+
method: "eth_getTransactionCount";
|
|
75
|
+
params: [address: string];
|
|
56
76
|
};
|
|
57
77
|
type GenLayerClient<TTransport extends Transport, TSimulatorChain extends SimulatorChain, TAccount extends Account> = Client<TTransport, TSimulatorChain, TAccount> & {
|
|
58
78
|
request: Client<TTransport, TSimulatorChain, TAccount>["request"] & {
|
|
@@ -62,20 +82,28 @@ type GenLayerClient<TTransport extends Transport, TSimulatorChain extends Simula
|
|
|
62
82
|
};
|
|
63
83
|
readContract: (args: {
|
|
64
84
|
account: Account;
|
|
65
|
-
address: Address;
|
|
85
|
+
address: Address$1;
|
|
66
86
|
functionName: string;
|
|
67
87
|
args: any[];
|
|
68
88
|
}) => Promise<any>;
|
|
69
89
|
writeContract: (args: {
|
|
70
90
|
account: Account;
|
|
71
|
-
address: Address;
|
|
91
|
+
address: Address$1;
|
|
72
92
|
functionName: string;
|
|
73
93
|
args: any[];
|
|
74
94
|
value: bigint;
|
|
75
95
|
}) => Promise<any>;
|
|
96
|
+
deployContract: (args: {
|
|
97
|
+
account: Account;
|
|
98
|
+
code: string;
|
|
99
|
+
args: CalldataEncodable[];
|
|
100
|
+
}) => Promise<any>;
|
|
76
101
|
getTransaction: (args: {
|
|
77
102
|
hash: TransactionHash;
|
|
78
103
|
}) => Promise<GenLayerTransaction>;
|
|
104
|
+
getCurrentNonce: (args: {
|
|
105
|
+
address: string;
|
|
106
|
+
}) => Promise<number>;
|
|
79
107
|
};
|
|
80
108
|
|
|
81
|
-
export { type Address as A, type GenLayerClient as G, type
|
|
109
|
+
export { type Address$1 as A, type CalldataEncodable as C, type GenLayerClient as G, type MethodDescription as M, type TransactionData as T, type GenLayerMethod as a, type TransactionHash as b, TransactionStatus as c, type GenLayerTransaction as d, type TransactionDataElement as e };
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
var _chunkBAGFDCQEcjs = require('./chunk-BAGFDCQE.cjs');
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkYI62SDKVcjs = require('./chunk-YI62SDKV.cjs');
|
|
6
8
|
require('./chunk-75ZPJI57.cjs');
|
|
7
9
|
|
|
8
10
|
// src/client/client.ts
|
|
@@ -19,12 +21,169 @@ function accountActions(client) {
|
|
|
19
21
|
method: "sim_fundAccount",
|
|
20
22
|
params: [address, amount]
|
|
21
23
|
});
|
|
24
|
+
},
|
|
25
|
+
getCurrentNonce: async ({ address }) => {
|
|
26
|
+
return client.request({
|
|
27
|
+
method: "eth_getTransactionCount",
|
|
28
|
+
params: [address || _optionalChain([client, 'access', _3 => _3.account, 'optionalAccess', _4 => _4.address])]
|
|
29
|
+
});
|
|
22
30
|
}
|
|
23
31
|
};
|
|
24
32
|
}
|
|
25
33
|
|
|
26
|
-
// src/
|
|
34
|
+
// src/abi/calldata/encoder.ts
|
|
35
|
+
|
|
36
|
+
var BITS_IN_TYPE = 3;
|
|
37
|
+
var TYPE_SPECIAL = 0;
|
|
38
|
+
var TYPE_PINT = 1;
|
|
39
|
+
var TYPE_NINT = 2;
|
|
40
|
+
var TYPE_BYTES = 3;
|
|
41
|
+
var TYPE_STR = 4;
|
|
42
|
+
var TYPE_ARR = 5;
|
|
43
|
+
var TYPE_MAP = 6;
|
|
44
|
+
var SPECIAL_NULL = 0 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
45
|
+
var SPECIAL_FALSE = 1 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
46
|
+
var SPECIAL_TRUE = 2 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
47
|
+
var SPECIAL_ADDR = 3 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
48
|
+
function reportError(msg, data) {
|
|
49
|
+
throw new Error(`invalid calldata input '${data}'`);
|
|
50
|
+
}
|
|
51
|
+
function writeNum(to, data) {
|
|
52
|
+
if (data === 0n) {
|
|
53
|
+
to.push(0);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
while (data > 0) {
|
|
57
|
+
let cur = Number(data & 0x7fn);
|
|
58
|
+
data >>= 7n;
|
|
59
|
+
if (data > 0) {
|
|
60
|
+
cur |= 128;
|
|
61
|
+
}
|
|
62
|
+
to.push(cur);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function encodeNumWithType(to, data, type) {
|
|
66
|
+
const res = data << BigInt(BITS_IN_TYPE) | BigInt(type);
|
|
67
|
+
writeNum(to, res);
|
|
68
|
+
}
|
|
69
|
+
function encodeNum(to, data) {
|
|
70
|
+
if (data >= 0n) {
|
|
71
|
+
encodeNumWithType(to, data, TYPE_PINT);
|
|
72
|
+
} else {
|
|
73
|
+
encodeNumWithType(to, -data - 1n, TYPE_NINT);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function compareString(l, r) {
|
|
77
|
+
for (let index = 0; index < l.length && index < r.length; index++) {
|
|
78
|
+
const cur = l[index] - r[index];
|
|
79
|
+
if (cur !== 0) {
|
|
80
|
+
return cur;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return l.length - r.length;
|
|
84
|
+
}
|
|
85
|
+
function encodeMap(to, arr) {
|
|
86
|
+
const newEntries = Array.from(
|
|
87
|
+
arr,
|
|
88
|
+
([k, v]) => [
|
|
89
|
+
Array.from(k, (x) => x.codePointAt(0)),
|
|
90
|
+
new TextEncoder().encode(k),
|
|
91
|
+
v
|
|
92
|
+
]
|
|
93
|
+
);
|
|
94
|
+
newEntries.sort((v1, v2) => compareString(v1[0], v2[0]));
|
|
95
|
+
for (let i = 1; i < newEntries.length; i++) {
|
|
96
|
+
if (compareString(newEntries[i - 1][0], newEntries[i][0]) === 0) {
|
|
97
|
+
throw new Error(`duplicate key '${new TextDecoder().decode(newEntries[i][1])}'`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
encodeNumWithType(to, BigInt(newEntries.length), TYPE_MAP);
|
|
101
|
+
for (const [_k, k, v] of newEntries) {
|
|
102
|
+
writeNum(to, BigInt(k.length));
|
|
103
|
+
for (const c of k) {
|
|
104
|
+
to.push(c);
|
|
105
|
+
}
|
|
106
|
+
encodeImpl(to, v);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function encodeImpl(to, data) {
|
|
110
|
+
if (data === null || data === void 0) {
|
|
111
|
+
to.push(SPECIAL_NULL);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (data === true) {
|
|
115
|
+
to.push(SPECIAL_TRUE);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (data === false) {
|
|
119
|
+
to.push(SPECIAL_FALSE);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
switch (typeof data) {
|
|
123
|
+
case "number": {
|
|
124
|
+
if (!Number.isInteger(data)) {
|
|
125
|
+
reportError("floats are not supported", data);
|
|
126
|
+
}
|
|
127
|
+
encodeNum(to, BigInt(data));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
case "bigint": {
|
|
131
|
+
encodeNum(to, data);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
case "string": {
|
|
135
|
+
const str = new TextEncoder().encode(data);
|
|
136
|
+
encodeNumWithType(to, BigInt(str.length), TYPE_STR);
|
|
137
|
+
for (const c of str) {
|
|
138
|
+
to.push(c);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
case "object": {
|
|
143
|
+
if (data instanceof Uint8Array) {
|
|
144
|
+
encodeNumWithType(to, BigInt(data.length), TYPE_BYTES);
|
|
145
|
+
for (const c of data) {
|
|
146
|
+
to.push(c);
|
|
147
|
+
}
|
|
148
|
+
} else if (data instanceof Array) {
|
|
149
|
+
encodeNumWithType(to, BigInt(data.length), TYPE_ARR);
|
|
150
|
+
for (const c of data) {
|
|
151
|
+
encodeImpl(to, c);
|
|
152
|
+
}
|
|
153
|
+
} else if (data instanceof Map) {
|
|
154
|
+
encodeMap(to, data);
|
|
155
|
+
} else if (data instanceof _chunkYI62SDKVcjs.Address) {
|
|
156
|
+
to.push(SPECIAL_ADDR);
|
|
157
|
+
for (const c of data.bytes) {
|
|
158
|
+
to.push(c);
|
|
159
|
+
}
|
|
160
|
+
} else if (Object.getPrototypeOf(data) === Object.prototype) {
|
|
161
|
+
encodeMap(
|
|
162
|
+
to,
|
|
163
|
+
Object.keys(data).map((k) => [k, data[k]])
|
|
164
|
+
);
|
|
165
|
+
} else {
|
|
166
|
+
reportError("unknown object type", data);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
default:
|
|
171
|
+
reportError("unknown base type", data);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function encode(data) {
|
|
175
|
+
const arr = [];
|
|
176
|
+
encodeImpl(arr, data);
|
|
177
|
+
return new Uint8Array(arr);
|
|
178
|
+
}
|
|
179
|
+
function serialize(data) {
|
|
180
|
+
return _viem.toRlp.call(void 0, data.map((param) => _viem.toHex.call(void 0, param)));
|
|
181
|
+
}
|
|
182
|
+
function encodeAndSerialize(data) {
|
|
183
|
+
return serialize([encode(data)]);
|
|
184
|
+
}
|
|
27
185
|
|
|
186
|
+
// src/contracts/actions.ts
|
|
28
187
|
var contractActions = (client) => {
|
|
29
188
|
return {
|
|
30
189
|
getContractSchema: async (address) => {
|
|
@@ -46,12 +205,10 @@ var contractActions = (client) => {
|
|
|
46
205
|
var overrideContractActions = (client) => {
|
|
47
206
|
client.readContract = async (args) => {
|
|
48
207
|
const { account, address, functionName, args: params } = args;
|
|
49
|
-
const
|
|
50
|
-
const data = [functionName, methodParamsAsString];
|
|
51
|
-
const encodedData = _viem.toRlp.call(void 0, data.map((param) => _viem.toHex.call(void 0, param)));
|
|
208
|
+
const encodedData = encodeAndSerialize({ method: functionName, args: params });
|
|
52
209
|
const requestParams = {
|
|
53
210
|
to: address,
|
|
54
|
-
from: _optionalChain([account, 'optionalAccess',
|
|
211
|
+
from: _optionalChain([account, 'optionalAccess', _5 => _5.address]) || _optionalChain([client, 'access', _6 => _6.account, 'optionalAccess', _7 => _7.address]),
|
|
55
212
|
data: encodedData
|
|
56
213
|
};
|
|
57
214
|
const result = await client.request({
|
|
@@ -62,23 +219,48 @@ var overrideContractActions = (client) => {
|
|
|
62
219
|
};
|
|
63
220
|
client.writeContract = async (args) => {
|
|
64
221
|
const { account, address, functionName, args: params, value = 0n } = args;
|
|
65
|
-
const
|
|
66
|
-
const data = [functionName, methodParamsAsString];
|
|
67
|
-
const encodedData = _viem.toRlp.call(void 0, data.map((param) => _viem.toHex.call(void 0, param)));
|
|
222
|
+
const encodedData = encodeAndSerialize({ method: functionName, args: params });
|
|
68
223
|
const senderAccount = account || client.account;
|
|
69
224
|
if (!senderAccount) {
|
|
70
225
|
throw new Error(
|
|
71
226
|
"No account set. Configure the client with an account or pass an account to this function."
|
|
72
227
|
);
|
|
73
228
|
}
|
|
74
|
-
if (!_optionalChain([senderAccount, 'optionalAccess',
|
|
229
|
+
if (!_optionalChain([senderAccount, 'optionalAccess', _8 => _8.signTransaction])) {
|
|
75
230
|
throw new Error("Account does not support signTransaction");
|
|
76
231
|
}
|
|
232
|
+
const nonce = await client.getCurrentNonce({ address: senderAccount.address });
|
|
77
233
|
const signedTransaction = await senderAccount.signTransaction({
|
|
78
234
|
data: encodedData,
|
|
79
235
|
to: address,
|
|
80
236
|
value,
|
|
81
|
-
type: "legacy"
|
|
237
|
+
type: "legacy",
|
|
238
|
+
nonce
|
|
239
|
+
});
|
|
240
|
+
const result = await client.request({
|
|
241
|
+
method: "eth_sendRawTransaction",
|
|
242
|
+
params: [signedTransaction]
|
|
243
|
+
});
|
|
244
|
+
return result;
|
|
245
|
+
};
|
|
246
|
+
client.deployContract = async (args) => {
|
|
247
|
+
const { account, code, args: constructorArgs } = args;
|
|
248
|
+
const data = [code, encode({ args: constructorArgs })];
|
|
249
|
+
const serializedData = serialize(data);
|
|
250
|
+
const senderAccount = account || client.account;
|
|
251
|
+
if (!senderAccount) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
"No account set. Configure the client with an account or pass an account to this function."
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (!_optionalChain([senderAccount, 'optionalAccess', _9 => _9.signTransaction])) {
|
|
257
|
+
throw new Error("Account does not support signTransaction");
|
|
258
|
+
}
|
|
259
|
+
const nonce = await client.getCurrentNonce({ address: senderAccount.address });
|
|
260
|
+
const signedTransaction = await senderAccount.signTransaction({
|
|
261
|
+
data: serializedData,
|
|
262
|
+
type: "legacy",
|
|
263
|
+
nonce
|
|
82
264
|
});
|
|
83
265
|
const result = await client.request({
|
|
84
266
|
method: "eth_sendRawTransaction",
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as viem from 'viem';
|
|
2
2
|
import { Transport, Account } from 'viem';
|
|
3
3
|
import { S as SimulatorChain } from './chains-CtZJFz4Q.cjs';
|
|
4
|
-
import { G as GenLayerClient } from './clients-
|
|
4
|
+
import { G as GenLayerClient } from './clients-BamlAEcy.cjs';
|
|
5
5
|
import * as abitype from 'abitype';
|
|
6
6
|
import * as viem__types_experimental_eip7702_types_authorization from 'viem/_types/experimental/eip7702/types/authorization';
|
|
7
7
|
import * as viem_accounts from 'viem/accounts';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as viem from 'viem';
|
|
2
2
|
import { Transport, Account } from 'viem';
|
|
3
3
|
import { S as SimulatorChain } from './chains-CtZJFz4Q.js';
|
|
4
|
-
import { G as GenLayerClient } from './clients-
|
|
4
|
+
import { G as GenLayerClient } from './clients-CJ820ePR.js';
|
|
5
5
|
import * as abitype from 'abitype';
|
|
6
6
|
import * as viem__types_experimental_eip7702_types_authorization from 'viem/_types/experimental/eip7702/types/authorization';
|
|
7
7
|
import * as viem_accounts from 'viem/accounts';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,9 @@ import {
|
|
|
2
2
|
chains_exports,
|
|
3
3
|
simulator
|
|
4
4
|
} from "./chunk-D7VZGQ4K.js";
|
|
5
|
-
import
|
|
5
|
+
import {
|
|
6
|
+
Address
|
|
7
|
+
} from "./chunk-M7SA3INM.js";
|
|
6
8
|
import "./chunk-MLKGABMK.js";
|
|
7
9
|
|
|
8
10
|
// src/client/client.ts
|
|
@@ -19,12 +21,169 @@ function accountActions(client) {
|
|
|
19
21
|
method: "sim_fundAccount",
|
|
20
22
|
params: [address, amount]
|
|
21
23
|
});
|
|
24
|
+
},
|
|
25
|
+
getCurrentNonce: async ({ address }) => {
|
|
26
|
+
return client.request({
|
|
27
|
+
method: "eth_getTransactionCount",
|
|
28
|
+
params: [address || client.account?.address]
|
|
29
|
+
});
|
|
22
30
|
}
|
|
23
31
|
};
|
|
24
32
|
}
|
|
25
33
|
|
|
34
|
+
// src/abi/calldata/encoder.ts
|
|
35
|
+
import { toHex, toRlp } from "viem";
|
|
36
|
+
var BITS_IN_TYPE = 3;
|
|
37
|
+
var TYPE_SPECIAL = 0;
|
|
38
|
+
var TYPE_PINT = 1;
|
|
39
|
+
var TYPE_NINT = 2;
|
|
40
|
+
var TYPE_BYTES = 3;
|
|
41
|
+
var TYPE_STR = 4;
|
|
42
|
+
var TYPE_ARR = 5;
|
|
43
|
+
var TYPE_MAP = 6;
|
|
44
|
+
var SPECIAL_NULL = 0 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
45
|
+
var SPECIAL_FALSE = 1 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
46
|
+
var SPECIAL_TRUE = 2 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
47
|
+
var SPECIAL_ADDR = 3 << BITS_IN_TYPE | TYPE_SPECIAL;
|
|
48
|
+
function reportError(msg, data) {
|
|
49
|
+
throw new Error(`invalid calldata input '${data}'`);
|
|
50
|
+
}
|
|
51
|
+
function writeNum(to, data) {
|
|
52
|
+
if (data === 0n) {
|
|
53
|
+
to.push(0);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
while (data > 0) {
|
|
57
|
+
let cur = Number(data & 0x7fn);
|
|
58
|
+
data >>= 7n;
|
|
59
|
+
if (data > 0) {
|
|
60
|
+
cur |= 128;
|
|
61
|
+
}
|
|
62
|
+
to.push(cur);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function encodeNumWithType(to, data, type) {
|
|
66
|
+
const res = data << BigInt(BITS_IN_TYPE) | BigInt(type);
|
|
67
|
+
writeNum(to, res);
|
|
68
|
+
}
|
|
69
|
+
function encodeNum(to, data) {
|
|
70
|
+
if (data >= 0n) {
|
|
71
|
+
encodeNumWithType(to, data, TYPE_PINT);
|
|
72
|
+
} else {
|
|
73
|
+
encodeNumWithType(to, -data - 1n, TYPE_NINT);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function compareString(l, r) {
|
|
77
|
+
for (let index = 0; index < l.length && index < r.length; index++) {
|
|
78
|
+
const cur = l[index] - r[index];
|
|
79
|
+
if (cur !== 0) {
|
|
80
|
+
return cur;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return l.length - r.length;
|
|
84
|
+
}
|
|
85
|
+
function encodeMap(to, arr) {
|
|
86
|
+
const newEntries = Array.from(
|
|
87
|
+
arr,
|
|
88
|
+
([k, v]) => [
|
|
89
|
+
Array.from(k, (x) => x.codePointAt(0)),
|
|
90
|
+
new TextEncoder().encode(k),
|
|
91
|
+
v
|
|
92
|
+
]
|
|
93
|
+
);
|
|
94
|
+
newEntries.sort((v1, v2) => compareString(v1[0], v2[0]));
|
|
95
|
+
for (let i = 1; i < newEntries.length; i++) {
|
|
96
|
+
if (compareString(newEntries[i - 1][0], newEntries[i][0]) === 0) {
|
|
97
|
+
throw new Error(`duplicate key '${new TextDecoder().decode(newEntries[i][1])}'`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
encodeNumWithType(to, BigInt(newEntries.length), TYPE_MAP);
|
|
101
|
+
for (const [_k, k, v] of newEntries) {
|
|
102
|
+
writeNum(to, BigInt(k.length));
|
|
103
|
+
for (const c of k) {
|
|
104
|
+
to.push(c);
|
|
105
|
+
}
|
|
106
|
+
encodeImpl(to, v);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function encodeImpl(to, data) {
|
|
110
|
+
if (data === null || data === void 0) {
|
|
111
|
+
to.push(SPECIAL_NULL);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (data === true) {
|
|
115
|
+
to.push(SPECIAL_TRUE);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (data === false) {
|
|
119
|
+
to.push(SPECIAL_FALSE);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
switch (typeof data) {
|
|
123
|
+
case "number": {
|
|
124
|
+
if (!Number.isInteger(data)) {
|
|
125
|
+
reportError("floats are not supported", data);
|
|
126
|
+
}
|
|
127
|
+
encodeNum(to, BigInt(data));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
case "bigint": {
|
|
131
|
+
encodeNum(to, data);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
case "string": {
|
|
135
|
+
const str = new TextEncoder().encode(data);
|
|
136
|
+
encodeNumWithType(to, BigInt(str.length), TYPE_STR);
|
|
137
|
+
for (const c of str) {
|
|
138
|
+
to.push(c);
|
|
139
|
+
}
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
case "object": {
|
|
143
|
+
if (data instanceof Uint8Array) {
|
|
144
|
+
encodeNumWithType(to, BigInt(data.length), TYPE_BYTES);
|
|
145
|
+
for (const c of data) {
|
|
146
|
+
to.push(c);
|
|
147
|
+
}
|
|
148
|
+
} else if (data instanceof Array) {
|
|
149
|
+
encodeNumWithType(to, BigInt(data.length), TYPE_ARR);
|
|
150
|
+
for (const c of data) {
|
|
151
|
+
encodeImpl(to, c);
|
|
152
|
+
}
|
|
153
|
+
} else if (data instanceof Map) {
|
|
154
|
+
encodeMap(to, data);
|
|
155
|
+
} else if (data instanceof Address) {
|
|
156
|
+
to.push(SPECIAL_ADDR);
|
|
157
|
+
for (const c of data.bytes) {
|
|
158
|
+
to.push(c);
|
|
159
|
+
}
|
|
160
|
+
} else if (Object.getPrototypeOf(data) === Object.prototype) {
|
|
161
|
+
encodeMap(
|
|
162
|
+
to,
|
|
163
|
+
Object.keys(data).map((k) => [k, data[k]])
|
|
164
|
+
);
|
|
165
|
+
} else {
|
|
166
|
+
reportError("unknown object type", data);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
default:
|
|
171
|
+
reportError("unknown base type", data);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function encode(data) {
|
|
175
|
+
const arr = [];
|
|
176
|
+
encodeImpl(arr, data);
|
|
177
|
+
return new Uint8Array(arr);
|
|
178
|
+
}
|
|
179
|
+
function serialize(data) {
|
|
180
|
+
return toRlp(data.map((param) => toHex(param)));
|
|
181
|
+
}
|
|
182
|
+
function encodeAndSerialize(data) {
|
|
183
|
+
return serialize([encode(data)]);
|
|
184
|
+
}
|
|
185
|
+
|
|
26
186
|
// src/contracts/actions.ts
|
|
27
|
-
import { toRlp, toHex } from "viem";
|
|
28
187
|
var contractActions = (client) => {
|
|
29
188
|
return {
|
|
30
189
|
getContractSchema: async (address) => {
|
|
@@ -46,9 +205,7 @@ var contractActions = (client) => {
|
|
|
46
205
|
var overrideContractActions = (client) => {
|
|
47
206
|
client.readContract = async (args) => {
|
|
48
207
|
const { account, address, functionName, args: params } = args;
|
|
49
|
-
const
|
|
50
|
-
const data = [functionName, methodParamsAsString];
|
|
51
|
-
const encodedData = toRlp(data.map((param) => toHex(param)));
|
|
208
|
+
const encodedData = encodeAndSerialize({ method: functionName, args: params });
|
|
52
209
|
const requestParams = {
|
|
53
210
|
to: address,
|
|
54
211
|
from: account?.address || client.account?.address,
|
|
@@ -62,9 +219,7 @@ var overrideContractActions = (client) => {
|
|
|
62
219
|
};
|
|
63
220
|
client.writeContract = async (args) => {
|
|
64
221
|
const { account, address, functionName, args: params, value = 0n } = args;
|
|
65
|
-
const
|
|
66
|
-
const data = [functionName, methodParamsAsString];
|
|
67
|
-
const encodedData = toRlp(data.map((param) => toHex(param)));
|
|
222
|
+
const encodedData = encodeAndSerialize({ method: functionName, args: params });
|
|
68
223
|
const senderAccount = account || client.account;
|
|
69
224
|
if (!senderAccount) {
|
|
70
225
|
throw new Error(
|
|
@@ -74,11 +229,38 @@ var overrideContractActions = (client) => {
|
|
|
74
229
|
if (!senderAccount?.signTransaction) {
|
|
75
230
|
throw new Error("Account does not support signTransaction");
|
|
76
231
|
}
|
|
232
|
+
const nonce = await client.getCurrentNonce({ address: senderAccount.address });
|
|
77
233
|
const signedTransaction = await senderAccount.signTransaction({
|
|
78
234
|
data: encodedData,
|
|
79
235
|
to: address,
|
|
80
236
|
value,
|
|
81
|
-
type: "legacy"
|
|
237
|
+
type: "legacy",
|
|
238
|
+
nonce
|
|
239
|
+
});
|
|
240
|
+
const result = await client.request({
|
|
241
|
+
method: "eth_sendRawTransaction",
|
|
242
|
+
params: [signedTransaction]
|
|
243
|
+
});
|
|
244
|
+
return result;
|
|
245
|
+
};
|
|
246
|
+
client.deployContract = async (args) => {
|
|
247
|
+
const { account, code, args: constructorArgs } = args;
|
|
248
|
+
const data = [code, encode({ args: constructorArgs })];
|
|
249
|
+
const serializedData = serialize(data);
|
|
250
|
+
const senderAccount = account || client.account;
|
|
251
|
+
if (!senderAccount) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
"No account set. Configure the client with an account or pass an account to this function."
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
if (!senderAccount?.signTransaction) {
|
|
257
|
+
throw new Error("Account does not support signTransaction");
|
|
258
|
+
}
|
|
259
|
+
const nonce = await client.getCurrentNonce({ address: senderAccount.address });
|
|
260
|
+
const signedTransaction = await senderAccount.signTransaction({
|
|
261
|
+
data: serializedData,
|
|
262
|
+
type: "legacy",
|
|
263
|
+
nonce
|
|
82
264
|
});
|
|
83
265
|
const result = await client.request({
|
|
84
266
|
method: "eth_sendRawTransaction",
|
package/dist/types/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunkYI62SDKVcjs = require('../chunk-YI62SDKV.cjs');
|
|
4
4
|
require('../chunk-75ZPJI57.cjs');
|
|
5
5
|
|
|
6
6
|
// src/types/accounts.ts
|
|
@@ -8,4 +8,4 @@ var _viem = require('viem');
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
exports.Account = _viem.Account; exports.TransactionStatus =
|
|
11
|
+
exports.Account = _viem.Account; exports.TransactionStatus = _chunkYI62SDKVcjs.TransactionStatus;
|
package/dist/types/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Address, G as GenLayerClient, a as GenLayerMethod,
|
|
1
|
+
export { A as Address, C as CalldataEncodable, G as GenLayerClient, a as GenLayerMethod, d as GenLayerTransaction, M as MethodDescription, T as TransactionData, e as TransactionDataElement, b as TransactionHash, c as TransactionStatus } from '../clients-BamlAEcy.cjs';
|
|
2
2
|
export { S as SimulatorChain } from '../chains-CtZJFz4Q.cjs';
|
|
3
3
|
export { Account } from 'viem';
|
|
4
4
|
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Address, G as GenLayerClient, a as GenLayerMethod,
|
|
1
|
+
export { A as Address, C as CalldataEncodable, G as GenLayerClient, a as GenLayerMethod, d as GenLayerTransaction, M as MethodDescription, T as TransactionData, e as TransactionDataElement, b as TransactionHash, c as TransactionStatus } from '../clients-CJ820ePR.js';
|
|
2
2
|
export { S as SimulatorChain } from '../chains-CtZJFz4Q.js';
|
|
3
3
|
export { Account } from 'viem';
|
|
4
4
|
|
package/dist/types/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genlayer-js",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"description": "GenLayer JavaScript SDK",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"eslint-plugin-import": "^2.30.0",
|
|
52
|
+
"typescript-parsec": "^0.3.4",
|
|
52
53
|
"viem": "^2.21.7"
|
|
53
54
|
}
|
|
54
55
|
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {toHex, toRlp} from "viem";
|
|
2
|
+
import type {CalldataEncodable, TransactionDataElement} from "../../types/calldata";
|
|
3
|
+
import {Address} from "../../types/calldata";
|
|
4
|
+
|
|
5
|
+
const BITS_IN_TYPE = 3;
|
|
6
|
+
|
|
7
|
+
const TYPE_SPECIAL = 0;
|
|
8
|
+
const TYPE_PINT = 1;
|
|
9
|
+
const TYPE_NINT = 2;
|
|
10
|
+
const TYPE_BYTES = 3;
|
|
11
|
+
const TYPE_STR = 4;
|
|
12
|
+
const TYPE_ARR = 5;
|
|
13
|
+
const TYPE_MAP = 6;
|
|
14
|
+
|
|
15
|
+
const SPECIAL_NULL = (0 << BITS_IN_TYPE) | TYPE_SPECIAL;
|
|
16
|
+
const SPECIAL_FALSE = (1 << BITS_IN_TYPE) | TYPE_SPECIAL;
|
|
17
|
+
const SPECIAL_TRUE = (2 << BITS_IN_TYPE) | TYPE_SPECIAL;
|
|
18
|
+
const SPECIAL_ADDR = (3 << BITS_IN_TYPE) | TYPE_SPECIAL;
|
|
19
|
+
|
|
20
|
+
function reportError(msg: string, data: CalldataEncodable): never {
|
|
21
|
+
throw new Error(`invalid calldata input '${data}'`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function writeNum(to: number[], data: bigint) {
|
|
25
|
+
if (data === 0n) {
|
|
26
|
+
to.push(0);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
while (data > 0) {
|
|
30
|
+
let cur = Number(data & 0x7fn);
|
|
31
|
+
data >>= 7n;
|
|
32
|
+
if (data > 0) {
|
|
33
|
+
cur |= 0x80;
|
|
34
|
+
}
|
|
35
|
+
to.push(cur);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function encodeNumWithType(to: number[], data: bigint, type: number) {
|
|
40
|
+
const res = (data << BigInt(BITS_IN_TYPE)) | BigInt(type);
|
|
41
|
+
writeNum(to, res);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function encodeNum(to: number[], data: bigint) {
|
|
45
|
+
if (data >= 0n) {
|
|
46
|
+
encodeNumWithType(to, data, TYPE_PINT);
|
|
47
|
+
} else {
|
|
48
|
+
encodeNumWithType(to, -data - 1n, TYPE_NINT);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function compareString(l: number[], r: number[]): number {
|
|
53
|
+
for (let index = 0; index < l.length && index < r.length; index++) {
|
|
54
|
+
const cur = l[index] - r[index];
|
|
55
|
+
if (cur !== 0) {
|
|
56
|
+
return cur;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return l.length - r.length;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function encodeMap(to: number[], arr: Iterable<[string, CalldataEncodable]>) {
|
|
63
|
+
// unicode code points array, utf8 encoded array, item
|
|
64
|
+
const newEntries: [number[], Uint8Array, CalldataEncodable][] = Array.from(
|
|
65
|
+
arr,
|
|
66
|
+
([k, v]): [number[], Uint8Array, CalldataEncodable] => [
|
|
67
|
+
Array.from(k, x => x.codePointAt(0)!),
|
|
68
|
+
new TextEncoder().encode(k),
|
|
69
|
+
v,
|
|
70
|
+
],
|
|
71
|
+
);
|
|
72
|
+
newEntries.sort((v1, v2) => compareString(v1[0], v2[0]));
|
|
73
|
+
for (let i = 1; i < newEntries.length; i++) {
|
|
74
|
+
if (compareString(newEntries[i - 1][0], newEntries[i][0]) === 0) {
|
|
75
|
+
throw new Error(`duplicate key '${new TextDecoder().decode(newEntries[i][1])}'`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
encodeNumWithType(to, BigInt(newEntries.length), TYPE_MAP);
|
|
80
|
+
for (const [_k, k, v] of newEntries) {
|
|
81
|
+
writeNum(to, BigInt(k.length));
|
|
82
|
+
for (const c of k) {
|
|
83
|
+
to.push(c);
|
|
84
|
+
}
|
|
85
|
+
encodeImpl(to, v);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function encodeImpl(to: number[], data: CalldataEncodable) {
|
|
90
|
+
if (data === null || data === undefined) {
|
|
91
|
+
to.push(SPECIAL_NULL);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (data === true) {
|
|
95
|
+
to.push(SPECIAL_TRUE);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (data === false) {
|
|
99
|
+
to.push(SPECIAL_FALSE);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
switch (typeof data) {
|
|
103
|
+
case "number": {
|
|
104
|
+
if (!Number.isInteger(data)) {
|
|
105
|
+
reportError("floats are not supported", data);
|
|
106
|
+
}
|
|
107
|
+
encodeNum(to, BigInt(data));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
case "bigint": {
|
|
111
|
+
encodeNum(to, data);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
case "string": {
|
|
115
|
+
const str = new TextEncoder().encode(data);
|
|
116
|
+
encodeNumWithType(to, BigInt(str.length), TYPE_STR);
|
|
117
|
+
for (const c of str) {
|
|
118
|
+
to.push(c);
|
|
119
|
+
}
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
case "object": {
|
|
123
|
+
if (data instanceof Uint8Array) {
|
|
124
|
+
encodeNumWithType(to, BigInt(data.length), TYPE_BYTES);
|
|
125
|
+
for (const c of data) {
|
|
126
|
+
to.push(c);
|
|
127
|
+
}
|
|
128
|
+
} else if (data instanceof Array) {
|
|
129
|
+
encodeNumWithType(to, BigInt(data.length), TYPE_ARR);
|
|
130
|
+
for (const c of data) {
|
|
131
|
+
encodeImpl(to, c);
|
|
132
|
+
}
|
|
133
|
+
} else if (data instanceof Map) {
|
|
134
|
+
encodeMap(to, data);
|
|
135
|
+
} else if (data instanceof Address) {
|
|
136
|
+
to.push(SPECIAL_ADDR);
|
|
137
|
+
for (const c of data.bytes) {
|
|
138
|
+
to.push(c);
|
|
139
|
+
}
|
|
140
|
+
} else if (Object.getPrototypeOf(data) === Object.prototype) {
|
|
141
|
+
encodeMap(
|
|
142
|
+
to,
|
|
143
|
+
Object.keys(data).map((k): [string, CalldataEncodable] => [k, data[k]]),
|
|
144
|
+
);
|
|
145
|
+
} else {
|
|
146
|
+
reportError("unknown object type", data);
|
|
147
|
+
}
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
default:
|
|
151
|
+
reportError("unknown base type", data);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function encode(data: CalldataEncodable): Uint8Array {
|
|
156
|
+
// FIXME: find a better growable type
|
|
157
|
+
const arr: number[] = [];
|
|
158
|
+
encodeImpl(arr, data);
|
|
159
|
+
return new Uint8Array(arr);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function serialize(data: TransactionDataElement[]): `0x${string}` {
|
|
163
|
+
return toRlp(data.map(param => toHex(param)));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export function encodeAndSerialize(data: CalldataEncodable): `0x${string}` {
|
|
167
|
+
return serialize([encode(data)]);
|
|
168
|
+
}
|
package/src/abi/index.ts
ADDED
package/src/accounts/actions.ts
CHANGED
|
@@ -18,5 +18,11 @@ export function accountActions<
|
|
|
18
18
|
params: [address, amount],
|
|
19
19
|
}) as Promise<TransactionHash>;
|
|
20
20
|
},
|
|
21
|
+
getCurrentNonce: async ({address}: {address: string}): Promise<number> => {
|
|
22
|
+
return client.request({
|
|
23
|
+
method: "eth_getTransactionCount",
|
|
24
|
+
params: [address || client.account?.address],
|
|
25
|
+
}) as Promise<number>;
|
|
26
|
+
},
|
|
21
27
|
};
|
|
22
28
|
}
|
package/src/contracts/actions.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {Transport, Account, Address} from "viem";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import {encode, serialize, encodeAndSerialize} from "@/abi/calldata/encoder";
|
|
4
|
+
import {ContractSchema, SimulatorChain, GenLayerClient, CalldataEncodable} from "@/types";
|
|
5
5
|
|
|
6
6
|
export const contractActions = (client: GenLayerClient<Transport, SimulatorChain, Account>) => {
|
|
7
7
|
return {
|
|
@@ -27,12 +27,10 @@ export const overrideContractActions = (client: GenLayerClient<Transport, Simula
|
|
|
27
27
|
account: Account;
|
|
28
28
|
address: Address;
|
|
29
29
|
functionName: string;
|
|
30
|
-
args:
|
|
30
|
+
args: CalldataEncodable[];
|
|
31
31
|
}): Promise<any> => {
|
|
32
32
|
const {account, address, functionName, args: params} = args;
|
|
33
|
-
const
|
|
34
|
-
const data = [functionName, methodParamsAsString];
|
|
35
|
-
const encodedData = toRlp(data.map(param => toHex(param)));
|
|
33
|
+
const encodedData = encodeAndSerialize({method: functionName, args: params});
|
|
36
34
|
|
|
37
35
|
const requestParams = {
|
|
38
36
|
to: address,
|
|
@@ -50,13 +48,11 @@ export const overrideContractActions = (client: GenLayerClient<Transport, Simula
|
|
|
50
48
|
account: Account;
|
|
51
49
|
address: Address;
|
|
52
50
|
functionName: string;
|
|
53
|
-
args:
|
|
51
|
+
args: CalldataEncodable[];
|
|
54
52
|
value: bigint;
|
|
55
53
|
}): Promise<any> => {
|
|
56
54
|
const {account, address, functionName, args: params, value = 0n} = args;
|
|
57
|
-
const
|
|
58
|
-
const data = [functionName, methodParamsAsString];
|
|
59
|
-
const encodedData = toRlp(data.map(param => toHex(param)));
|
|
55
|
+
const encodedData = encodeAndSerialize({method: functionName, args: params});
|
|
60
56
|
|
|
61
57
|
const senderAccount = account || client.account;
|
|
62
58
|
if (!senderAccount) {
|
|
@@ -69,11 +65,14 @@ export const overrideContractActions = (client: GenLayerClient<Transport, Simula
|
|
|
69
65
|
throw new Error("Account does not support signTransaction");
|
|
70
66
|
}
|
|
71
67
|
|
|
68
|
+
const nonce = await client.getCurrentNonce({address: senderAccount.address});
|
|
69
|
+
|
|
72
70
|
const signedTransaction = await senderAccount.signTransaction({
|
|
73
71
|
data: encodedData,
|
|
74
72
|
to: address,
|
|
75
73
|
value,
|
|
76
74
|
type: "legacy",
|
|
75
|
+
nonce,
|
|
77
76
|
});
|
|
78
77
|
const result = await client.request({
|
|
79
78
|
method: "eth_sendRawTransaction",
|
|
@@ -82,5 +81,36 @@ export const overrideContractActions = (client: GenLayerClient<Transport, Simula
|
|
|
82
81
|
return result;
|
|
83
82
|
};
|
|
84
83
|
|
|
84
|
+
client.deployContract = async (args: {account: Account; code: string; args: CalldataEncodable[]}) => {
|
|
85
|
+
const {account, code, args: constructorArgs} = args;
|
|
86
|
+
const data = [code, encode({args: constructorArgs})];
|
|
87
|
+
const serializedData = serialize(data);
|
|
88
|
+
|
|
89
|
+
const senderAccount = account || client.account;
|
|
90
|
+
if (!senderAccount) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
"No account set. Configure the client with an account or pass an account to this function.",
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!senderAccount?.signTransaction) {
|
|
97
|
+
throw new Error("Account does not support signTransaction");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const nonce = await client.getCurrentNonce({address: senderAccount.address});
|
|
101
|
+
|
|
102
|
+
const signedTransaction = await senderAccount.signTransaction({
|
|
103
|
+
data: serializedData,
|
|
104
|
+
type: "legacy",
|
|
105
|
+
nonce,
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const result = await client.request({
|
|
109
|
+
method: "eth_sendRawTransaction",
|
|
110
|
+
params: [signedTransaction],
|
|
111
|
+
});
|
|
112
|
+
return result;
|
|
113
|
+
};
|
|
114
|
+
|
|
85
115
|
return client;
|
|
86
116
|
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export class Address {
|
|
2
|
+
bytes: Uint8Array;
|
|
3
|
+
|
|
4
|
+
constructor(addr: Uint8Array) {
|
|
5
|
+
if (addr.length != 32) {
|
|
6
|
+
throw new Error(`invalid address length ${addr}`);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
this.bytes = addr;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type CalldataEncodable =
|
|
14
|
+
| null
|
|
15
|
+
| boolean
|
|
16
|
+
| Address
|
|
17
|
+
| number
|
|
18
|
+
| bigint
|
|
19
|
+
| string
|
|
20
|
+
| Uint8Array /// bytes
|
|
21
|
+
| Address
|
|
22
|
+
| Array<CalldataEncodable>
|
|
23
|
+
| Map<string, CalldataEncodable>
|
|
24
|
+
| {[key: string]: CalldataEncodable}; /// also a "map"
|
|
25
|
+
|
|
26
|
+
export type MethodDescription = {
|
|
27
|
+
method: string;
|
|
28
|
+
|
|
29
|
+
args: Array<CalldataEncodable>;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type TransactionData = {
|
|
33
|
+
method: string;
|
|
34
|
+
|
|
35
|
+
args: CalldataEncodable[];
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export type TransactionDataElement = string | number | bigint | boolean | Uint8Array;
|
package/src/types/clients.ts
CHANGED
|
@@ -2,6 +2,7 @@ import {Account, Transport, Client} from "viem";
|
|
|
2
2
|
import {GenLayerTransaction, TransactionHash} from "./transactions";
|
|
3
3
|
import {SimulatorChain} from "./chains";
|
|
4
4
|
import {Address} from "./accounts";
|
|
5
|
+
import {CalldataEncodable} from "./calldata";
|
|
5
6
|
|
|
6
7
|
export type GenLayerMethod =
|
|
7
8
|
| {method: "sim_fundAccount"; params: [address: string, amount: number]}
|
|
@@ -9,7 +10,8 @@ export type GenLayerMethod =
|
|
|
9
10
|
| {method: "eth_call"; params: [requestParams: any, blockNumberOrHash: string]}
|
|
10
11
|
| {method: "eth_sedRawTransaction"; params: [signedTransaction: string]}
|
|
11
12
|
| {method: "gen_getContractSchema"; params: [address: string]}
|
|
12
|
-
| {method: "gen_getContractSchemaForCode"; params: [contractCode: string]}
|
|
13
|
+
| {method: "gen_getContractSchemaForCode"; params: [contractCode: string]}
|
|
14
|
+
| {method: "eth_getTransactionCount"; params: [address: string]};
|
|
13
15
|
|
|
14
16
|
export type GenLayerClient<
|
|
15
17
|
TTransport extends Transport,
|
|
@@ -34,5 +36,7 @@ export type GenLayerClient<
|
|
|
34
36
|
args: any[];
|
|
35
37
|
value: bigint;
|
|
36
38
|
}) => Promise<any>;
|
|
39
|
+
deployContract: (args: {account: Account; code: string; args: CalldataEncodable[]}) => Promise<any>;
|
|
37
40
|
getTransaction: (args: {hash: TransactionHash}) => Promise<GenLayerTransaction>;
|
|
41
|
+
getCurrentNonce: (args: {address: string}) => Promise<number>;
|
|
38
42
|
};
|
package/src/types/index.ts
CHANGED