@dag-kit/kit 1.0.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/dist/esm/clients/actions/contract.js +42 -0
- package/dist/esm/clients/actions/example.js +211 -0
- package/dist/esm/clients/actions/example2.js +47 -0
- package/dist/esm/clients/actions/index.js +1 -0
- package/dist/esm/clients/actions/main.js +266 -0
- package/dist/esm/clients/actions/test.js +1 -0
- package/dist/esm/clients/chains.js +14 -0
- package/dist/esm/clients/types.js +1 -0
- package/dist/esm/exports/index.js +1 -0
- package/dist/esm/script.js +1 -0
- package/package.json +67 -0
- package/src/clients/actions/contract.ts +42 -0
- package/src/clients/actions/example.ts +252 -0
- package/src/clients/actions/example2.ts +57 -0
- package/src/clients/actions/index.ts +0 -0
- package/src/clients/actions/main.ts +376 -0
- package/src/clients/actions/test.ts +0 -0
- package/src/clients/chains.ts +16 -0
- package/src/clients/types.ts +44 -0
- package/src/exports/index.ts +8 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export const abi = [
|
|
2
|
+
{
|
|
3
|
+
inputs: [],
|
|
4
|
+
name: "decrement",
|
|
5
|
+
outputs: [],
|
|
6
|
+
stateMutability: "nonpayable",
|
|
7
|
+
type: "function",
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
inputs: [],
|
|
11
|
+
name: "increment",
|
|
12
|
+
outputs: [],
|
|
13
|
+
stateMutability: "nonpayable",
|
|
14
|
+
type: "function",
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
inputs: [],
|
|
18
|
+
name: "getNum",
|
|
19
|
+
outputs: [
|
|
20
|
+
{
|
|
21
|
+
internalType: "uint256",
|
|
22
|
+
name: "",
|
|
23
|
+
type: "uint256",
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
stateMutability: "view",
|
|
27
|
+
type: "function",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
inputs: [],
|
|
31
|
+
name: "num",
|
|
32
|
+
outputs: [
|
|
33
|
+
{
|
|
34
|
+
internalType: "uint256",
|
|
35
|
+
name: "",
|
|
36
|
+
type: "uint256",
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
stateMutability: "view",
|
|
40
|
+
type: "function",
|
|
41
|
+
},
|
|
42
|
+
];
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { defineChain } from "viem";
|
|
2
|
+
import { createDagAAClient, parseDAG } from "./main";
|
|
3
|
+
import { abi } from "./contract";
|
|
4
|
+
import { config as dotenvConfig } from "dotenv";
|
|
5
|
+
dotenvConfig();
|
|
6
|
+
// ==============================================================================
|
|
7
|
+
// Configuration
|
|
8
|
+
// ==============================================================================
|
|
9
|
+
const awakening = defineChain({
|
|
10
|
+
id: 1043,
|
|
11
|
+
name: "Awakening Testnet",
|
|
12
|
+
nativeCurrency: { decimals: 18, name: "Dag", symbol: "DAG" },
|
|
13
|
+
rpcUrls: { default: { http: ["https://relay.awakening.bdagscan.com"] } },
|
|
14
|
+
blockExplorers: {
|
|
15
|
+
default: { name: "Explorer", url: "https://awakening.bdagscan.com/" },
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
// Your contract ABI
|
|
19
|
+
const counterAbi = [
|
|
20
|
+
{
|
|
21
|
+
name: "increment",
|
|
22
|
+
type: "function",
|
|
23
|
+
stateMutability: "nonpayable",
|
|
24
|
+
inputs: [],
|
|
25
|
+
outputs: [],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "counter",
|
|
29
|
+
type: "function",
|
|
30
|
+
stateMutability: "view",
|
|
31
|
+
inputs: [],
|
|
32
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
// ==============================================================================
|
|
36
|
+
// Example 1: Basic Usage
|
|
37
|
+
// ==============================================================================
|
|
38
|
+
const PRIVATE_KEY_1 = process.env.PRIVATE_KEY_2;
|
|
39
|
+
async function basicExample() {
|
|
40
|
+
console.log("\nš¦ Example 1: Basic Usage");
|
|
41
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
42
|
+
// Create the client
|
|
43
|
+
const client = createDagAAClient({
|
|
44
|
+
chain: awakening,
|
|
45
|
+
rpcUrl: "https://relay.awakening.bdagscan.com",
|
|
46
|
+
bundlerUrl: "http://0.0.0.0:3000",
|
|
47
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
48
|
+
});
|
|
49
|
+
// Connect to your existing smart account
|
|
50
|
+
await client.connectSmartAccount({
|
|
51
|
+
owner: PRIVATE_KEY_1,
|
|
52
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
53
|
+
});
|
|
54
|
+
// Get account info
|
|
55
|
+
const address = client.getAddress();
|
|
56
|
+
const balance = await client.getBalance();
|
|
57
|
+
const isDeployed = await client.isDeployed();
|
|
58
|
+
const nonce = await client.getNonce();
|
|
59
|
+
console.log(`Address: ${address}`);
|
|
60
|
+
console.log(`Balance: ${Number(balance) / 1e18} DAG`);
|
|
61
|
+
console.log(`Deployed: ${isDeployed ? "Yes" : "No"}`);
|
|
62
|
+
console.log(`Nonce: ${nonce}`);
|
|
63
|
+
}
|
|
64
|
+
// ==============================================================================
|
|
65
|
+
// Example 2: Send Simple Transfer
|
|
66
|
+
// ==============================================================================
|
|
67
|
+
async function transferExample() {
|
|
68
|
+
console.log("\nšø Example 2: Send Transfer");
|
|
69
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
70
|
+
const client = createDagAAClient({
|
|
71
|
+
chain: awakening,
|
|
72
|
+
rpcUrl: "https://relay.awakening.bdagscan.com",
|
|
73
|
+
bundlerUrl: "http://0.0.0.0:3000",
|
|
74
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
75
|
+
});
|
|
76
|
+
await client.connectSmartAccount({
|
|
77
|
+
owner: PRIVATE_KEY_1,
|
|
78
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
79
|
+
});
|
|
80
|
+
// Send 0.01 DAG to an address
|
|
81
|
+
const txHash = await client.sendUserOperation({
|
|
82
|
+
target: "0x1749be926ef79a63a285b01263f7ddc350d435e6",
|
|
83
|
+
value: parseDAG("1"), // 0.01 DAG
|
|
84
|
+
maxFeePerGas: 50000000000n,
|
|
85
|
+
maxPriorityFeePerGas: 50000000000n,
|
|
86
|
+
});
|
|
87
|
+
console.log(`Transaction: ${txHash}`);
|
|
88
|
+
}
|
|
89
|
+
// ==============================================================================
|
|
90
|
+
// Example 3: Call Smart Contract (Write)
|
|
91
|
+
// ==============================================================================
|
|
92
|
+
async function contractWriteExample() {
|
|
93
|
+
console.log("\nš Example 3: Contract Write");
|
|
94
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
95
|
+
const client = createDagAAClient({
|
|
96
|
+
chain: awakening,
|
|
97
|
+
rpcUrl: "https://relay.awakening.bdagscan.com",
|
|
98
|
+
bundlerUrl: "http://0.0.0.0:3000",
|
|
99
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
100
|
+
});
|
|
101
|
+
await client.connectSmartAccount({
|
|
102
|
+
owner: PRIVATE_KEY_1,
|
|
103
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
104
|
+
});
|
|
105
|
+
// Call increment() on counter contract
|
|
106
|
+
const txHash = await client.writeContract({
|
|
107
|
+
address: "0x692e69cA1Fe89eF72ca94B0E3a32A92835501a08",
|
|
108
|
+
abi,
|
|
109
|
+
functionName: "increment",
|
|
110
|
+
maxFeePerGas: 50000000000n,
|
|
111
|
+
maxPriorityFeePerGas: 50000000000n,
|
|
112
|
+
});
|
|
113
|
+
console.log(`Transaction: ${txHash}`);
|
|
114
|
+
console.log(`https://awakening.bdagscan.com/tx/${txHash}`);
|
|
115
|
+
}
|
|
116
|
+
// ==============================================================================
|
|
117
|
+
// Example 4: Read Contract Data
|
|
118
|
+
// ==============================================================================
|
|
119
|
+
async function contractReadExample() {
|
|
120
|
+
console.log("\nš Example 4: Contract Read");
|
|
121
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
122
|
+
const client = createDagAAClient({
|
|
123
|
+
chain: awakening,
|
|
124
|
+
rpcUrl: "https://relay.awakening.bdagscan.com",
|
|
125
|
+
bundlerUrl: "http://0.0.0.0:3000",
|
|
126
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
127
|
+
});
|
|
128
|
+
await client.connectSmartAccount({
|
|
129
|
+
owner: PRIVATE_KEY_1,
|
|
130
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
131
|
+
});
|
|
132
|
+
// Read counter value
|
|
133
|
+
const counterValue = await client.readContract({
|
|
134
|
+
address: "0x692e69cA1Fe89eF72ca94B0E3a32A92835501a08",
|
|
135
|
+
abi,
|
|
136
|
+
functionName: "getNum",
|
|
137
|
+
});
|
|
138
|
+
console.log(`Counter value: ${counterValue}`);
|
|
139
|
+
}
|
|
140
|
+
// ==============================================================================
|
|
141
|
+
// Example 5: Batch Operations
|
|
142
|
+
// ==============================================================================
|
|
143
|
+
async function batchExample() {
|
|
144
|
+
console.log("\nš¦ Example 5: Batch Operations");
|
|
145
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
146
|
+
const client = createDagAAClient({
|
|
147
|
+
chain: awakening,
|
|
148
|
+
rpcUrl: "https://relay.awakening.bdagscan.com",
|
|
149
|
+
bundlerUrl: "http://0.0.0.0:3000",
|
|
150
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
151
|
+
});
|
|
152
|
+
await client.connectSmartAccount({
|
|
153
|
+
owner: PRIVATE_KEY_1,
|
|
154
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
155
|
+
});
|
|
156
|
+
// Send multiple operations
|
|
157
|
+
const hashes = await client.sendBatchUserOperations([
|
|
158
|
+
{
|
|
159
|
+
target: "0x1749be926ef79a63a285b01263f7ddc350d435e6",
|
|
160
|
+
value: parseDAG("0.5"),
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
target: "0x8371e519177f81b93287f750dcd06ce894c12cc5",
|
|
164
|
+
value: parseDAG("0.5"),
|
|
165
|
+
},
|
|
166
|
+
]);
|
|
167
|
+
console.log(`Sent ${hashes.length} operations`);
|
|
168
|
+
hashes.forEach((hash, i) => {
|
|
169
|
+
console.log(` ${i + 1}. ${hash}`);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// ==============================================================================
|
|
173
|
+
// Example 6: Fund Account
|
|
174
|
+
// ==============================================================================
|
|
175
|
+
async function fundingExample() {
|
|
176
|
+
console.log("\nš° Example 6: Fund Account");
|
|
177
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
178
|
+
const client = createDagAAClient({
|
|
179
|
+
chain: awakening,
|
|
180
|
+
rpcUrl: "https://relay.awakening.bdagscan.com",
|
|
181
|
+
bundlerUrl: "http://0.0.0.0:3000",
|
|
182
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
183
|
+
});
|
|
184
|
+
await client.connectSmartAccount({
|
|
185
|
+
owner: PRIVATE_KEY_1,
|
|
186
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
187
|
+
});
|
|
188
|
+
// Fund from EOA
|
|
189
|
+
const txHash = await client.fundAccount(parseDAG("1"), // 1 DAG
|
|
190
|
+
"0x5810098e367422376897bb2645c5ada5850a99aeec0505a58d38853ebd7f9f31" // From this private key
|
|
191
|
+
);
|
|
192
|
+
console.log(`Funded: ${txHash}`);
|
|
193
|
+
}
|
|
194
|
+
// ==============================================================================
|
|
195
|
+
// Run Examples
|
|
196
|
+
// ==============================================================================
|
|
197
|
+
async function main() {
|
|
198
|
+
try {
|
|
199
|
+
// Run the example you want
|
|
200
|
+
// await basicExample();
|
|
201
|
+
// await transferExample();
|
|
202
|
+
// await contractWriteExample();
|
|
203
|
+
await contractReadExample();
|
|
204
|
+
// await batchExample();
|
|
205
|
+
// await fundingExample();
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error("Error:", error);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
main();
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { awakening } from "../chains";
|
|
2
|
+
import { createDagAAClient, parseDAG } from "./main";
|
|
3
|
+
import { config as dotenvConfig } from "dotenv";
|
|
4
|
+
dotenvConfig();
|
|
5
|
+
const PRIVATE_KEY_2 = process.env.PRIVATE_KEY_1;
|
|
6
|
+
(async () => {
|
|
7
|
+
console.log("Sending Simple Transaction");
|
|
8
|
+
const client = createDagAAClient({
|
|
9
|
+
chain: awakening.chain_config,
|
|
10
|
+
rpcUrl: "https://rpc.awakening.bdagscan.com",
|
|
11
|
+
bundlerUrl: awakening.bundler_rpc,
|
|
12
|
+
factoryAddress: "0x8FaB6DF00085eb05D5F2C1FA46a6E539587ae3f3",
|
|
13
|
+
});
|
|
14
|
+
await client.connectSmartAccount({
|
|
15
|
+
owner: "0x6b0f66a03b67d7b9eaa6c31123ffe5bf2ee58eb40ab86c8a14d6f1294838b0c8",
|
|
16
|
+
accountAddress: "0xDe10aaC59f659fA154C063153AB3f7Cca1fb23A5",
|
|
17
|
+
});
|
|
18
|
+
// Send 0.01 DAG to an address
|
|
19
|
+
const txHash = await client.sendUserOperation({
|
|
20
|
+
target: "0x1749be926ef79a63a285b01263f7ddc350d435e6",
|
|
21
|
+
value: parseDAG("1"), // 0.01 DAG
|
|
22
|
+
maxFeePerGas: 50000000000n,
|
|
23
|
+
maxPriorityFeePerGas: 50000000000n,
|
|
24
|
+
});
|
|
25
|
+
console.log(`Transaction: ${txHash}`);
|
|
26
|
+
console.log("\nš¦ Example : Batch Operations");
|
|
27
|
+
console.log("āāāāāāāāāāāāāāāāāāāāāāāāāāā\n");
|
|
28
|
+
await client.connectSmartAccount({
|
|
29
|
+
owner: PRIVATE_KEY_2,
|
|
30
|
+
accountAddress: "0x7fd5385efcB7B2898933288948a9496CDc0fA8ee",
|
|
31
|
+
});
|
|
32
|
+
// Send multiple operations
|
|
33
|
+
const hashes = await client.sendBatchUserOperations([
|
|
34
|
+
{
|
|
35
|
+
target: "0x1749be926ef79a63a285b01263f7ddc350d435e6",
|
|
36
|
+
value: parseDAG("0.5"),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
target: "0x8371e519177f81b93287f750dcd06ce894c12cc5",
|
|
40
|
+
value: parseDAG("0.5"),
|
|
41
|
+
},
|
|
42
|
+
]);
|
|
43
|
+
console.log(`Sent ${hashes.length} operations`);
|
|
44
|
+
hashes.forEach((hash, i) => {
|
|
45
|
+
console.log(` ${i + 1}. ${hash}`);
|
|
46
|
+
});
|
|
47
|
+
})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// ==============================================================================
|
|
2
|
+
// DAG AA SDK - BlockDAG Account Abstraction SDK
|
|
3
|
+
// Inspired by Alchemy AA SDK
|
|
4
|
+
// ==============================================================================
|
|
5
|
+
import { createPublicClient, createWalletClient, http, encodeFunctionData, parseEther, } from "viem";
|
|
6
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
7
|
+
import { toSimpleSmartAccount } from "permissionless/accounts";
|
|
8
|
+
import { createPimlicoClient } from "permissionless/clients/pimlico";
|
|
9
|
+
import { entryPoint06Address } from "viem/account-abstraction";
|
|
10
|
+
import { createSmartAccountClient } from "permissionless";
|
|
11
|
+
// ==============================================================================
|
|
12
|
+
// Main SDK Class
|
|
13
|
+
// ==============================================================================
|
|
14
|
+
export class DagAAClient {
|
|
15
|
+
config;
|
|
16
|
+
publicClient;
|
|
17
|
+
walletClient;
|
|
18
|
+
bundlerClient = null;
|
|
19
|
+
smartAccount = null;
|
|
20
|
+
smartAccountClient = null;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = {
|
|
23
|
+
...config,
|
|
24
|
+
entryPointAddress: config.entryPointAddress || entryPoint06Address,
|
|
25
|
+
};
|
|
26
|
+
this.publicClient = createPublicClient({
|
|
27
|
+
chain: config.chain,
|
|
28
|
+
transport: http(config.rpcUrl),
|
|
29
|
+
});
|
|
30
|
+
this.walletClient = createWalletClient({
|
|
31
|
+
chain: config.chain,
|
|
32
|
+
transport: http(config.rpcUrl),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
// ==============================================================================
|
|
36
|
+
// Smart Account Management
|
|
37
|
+
// ==============================================================================
|
|
38
|
+
async connectSmartAccount(accountConfig) {
|
|
39
|
+
const owner = privateKeyToAccount(accountConfig.owner);
|
|
40
|
+
const signingClient = createWalletClient({
|
|
41
|
+
account: owner,
|
|
42
|
+
chain: this.config.chain,
|
|
43
|
+
transport: http(this.config.rpcUrl),
|
|
44
|
+
});
|
|
45
|
+
if (accountConfig.accountAddress) {
|
|
46
|
+
// Use existing account
|
|
47
|
+
this.smartAccount = await toSimpleSmartAccount({
|
|
48
|
+
client: signingClient,
|
|
49
|
+
owner: owner,
|
|
50
|
+
factoryAddress: this.config.factoryAddress,
|
|
51
|
+
entryPoint: {
|
|
52
|
+
address: this.config.entryPointAddress,
|
|
53
|
+
version: "0.6",
|
|
54
|
+
},
|
|
55
|
+
address: accountConfig.accountAddress,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// Create new account
|
|
60
|
+
this.smartAccount = await toSimpleSmartAccount({
|
|
61
|
+
client: signingClient,
|
|
62
|
+
owner: owner,
|
|
63
|
+
factoryAddress: this.config.factoryAddress,
|
|
64
|
+
entryPoint: {
|
|
65
|
+
address: this.config.entryPointAddress,
|
|
66
|
+
version: "0.6",
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
// Create bundler client
|
|
71
|
+
this.bundlerClient = createPimlicoClient({
|
|
72
|
+
transport: http(this.config.bundlerUrl),
|
|
73
|
+
entryPoint: {
|
|
74
|
+
address: this.config.entryPointAddress,
|
|
75
|
+
version: "0.6",
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
// Create smart account client
|
|
79
|
+
this.smartAccountClient = createSmartAccountClient({
|
|
80
|
+
bundlerTransport: http(this.config.bundlerUrl),
|
|
81
|
+
chain: this.config.chain,
|
|
82
|
+
account: this.smartAccount,
|
|
83
|
+
});
|
|
84
|
+
console.log(`ā
Connected to smart account: ${this.smartAccount.address}`);
|
|
85
|
+
return this.smartAccount.address;
|
|
86
|
+
}
|
|
87
|
+
// ==============================================================================
|
|
88
|
+
// Account Information
|
|
89
|
+
// ==============================================================================
|
|
90
|
+
getAddress() {
|
|
91
|
+
if (!this.smartAccount) {
|
|
92
|
+
throw new Error("Smart account not connected. Call connectSmartAccount() first.");
|
|
93
|
+
}
|
|
94
|
+
return this.smartAccount.address;
|
|
95
|
+
}
|
|
96
|
+
async getBalance() {
|
|
97
|
+
if (!this.smartAccount) {
|
|
98
|
+
throw new Error("Smart account not connected");
|
|
99
|
+
}
|
|
100
|
+
return await this.publicClient.getBalance({
|
|
101
|
+
address: this.smartAccount.address,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async isDeployed() {
|
|
105
|
+
if (!this.smartAccount) {
|
|
106
|
+
throw new Error("Smart account not connected");
|
|
107
|
+
}
|
|
108
|
+
const code = await this.publicClient.getCode({
|
|
109
|
+
address: this.smartAccount.address,
|
|
110
|
+
});
|
|
111
|
+
return code !== undefined && code !== "0x";
|
|
112
|
+
}
|
|
113
|
+
async getNonce() {
|
|
114
|
+
if (!this.smartAccount) {
|
|
115
|
+
throw new Error("Smart account not connected");
|
|
116
|
+
}
|
|
117
|
+
return await this.publicClient.readContract({
|
|
118
|
+
address: this.config.entryPointAddress,
|
|
119
|
+
abi: [
|
|
120
|
+
{
|
|
121
|
+
name: "getNonce",
|
|
122
|
+
type: "function",
|
|
123
|
+
stateMutability: "view",
|
|
124
|
+
inputs: [
|
|
125
|
+
{ name: "sender", type: "address" },
|
|
126
|
+
{ name: "key", type: "uint192" },
|
|
127
|
+
],
|
|
128
|
+
outputs: [{ name: "nonce", type: "uint256" }],
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
functionName: "getNonce",
|
|
132
|
+
args: [this.smartAccount.address, 0n],
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// ==============================================================================
|
|
136
|
+
// Send UserOperations
|
|
137
|
+
// ==============================================================================
|
|
138
|
+
async sendUserOperation(params) {
|
|
139
|
+
if (!this.smartAccountClient) {
|
|
140
|
+
throw new Error("Smart account not connected");
|
|
141
|
+
}
|
|
142
|
+
const { target, data = "0x", value = 0n, maxFeePerGas, maxPriorityFeePerGas, callGasLimit = 150000n, verificationGasLimit = 300000n, preVerificationGas = 100000n, } = params;
|
|
143
|
+
// Get gas prices if not provided
|
|
144
|
+
let gasPrices = {
|
|
145
|
+
maxFeePerGas: maxFeePerGas,
|
|
146
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas,
|
|
147
|
+
};
|
|
148
|
+
if (!maxFeePerGas || !maxPriorityFeePerGas) {
|
|
149
|
+
const estimatedGas = await this.bundlerClient.getUserOperationGasPrice();
|
|
150
|
+
gasPrices = {
|
|
151
|
+
maxFeePerGas: maxFeePerGas || estimatedGas.fast.maxFeePerGas,
|
|
152
|
+
maxPriorityFeePerGas: maxPriorityFeePerGas || estimatedGas.fast.maxPriorityFeePerGas,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
console.log("Sending UserOperation...");
|
|
156
|
+
console.log(` Target: ${target}`);
|
|
157
|
+
console.log(` Value: ${value}`);
|
|
158
|
+
console.log(` Gas: ${gasPrices.maxFeePerGas} / ${gasPrices.maxPriorityFeePerGas}`);
|
|
159
|
+
const userOpHash = await this.smartAccountClient.sendTransaction({
|
|
160
|
+
calls: [
|
|
161
|
+
{
|
|
162
|
+
to: target,
|
|
163
|
+
value: value,
|
|
164
|
+
data: data,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
maxFeePerGas: gasPrices.maxFeePerGas,
|
|
168
|
+
maxPriorityFeePerGas: gasPrices.maxPriorityFeePerGas,
|
|
169
|
+
callGasLimit,
|
|
170
|
+
verificationGasLimit,
|
|
171
|
+
preVerificationGas,
|
|
172
|
+
});
|
|
173
|
+
console.log(`ā
UserOperation sent: ${userOpHash}`);
|
|
174
|
+
return userOpHash;
|
|
175
|
+
}
|
|
176
|
+
// ==============================================================================
|
|
177
|
+
// Contract Interactions
|
|
178
|
+
// ==============================================================================
|
|
179
|
+
async writeContract(params) {
|
|
180
|
+
const { address, abi, functionName, args = [], value = 0n } = params;
|
|
181
|
+
const data = encodeFunctionData({
|
|
182
|
+
abi,
|
|
183
|
+
functionName,
|
|
184
|
+
args,
|
|
185
|
+
});
|
|
186
|
+
return await this.sendUserOperation({
|
|
187
|
+
target: address,
|
|
188
|
+
data,
|
|
189
|
+
value,
|
|
190
|
+
maxFeePerGas: params.maxFeePerGas,
|
|
191
|
+
maxPriorityFeePerGas: params.maxPriorityFeePerGas,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
async readContract(params) {
|
|
195
|
+
return await this.publicClient.readContract({
|
|
196
|
+
address: params.address,
|
|
197
|
+
abi: params.abi,
|
|
198
|
+
functionName: params.functionName,
|
|
199
|
+
args: params.args || [],
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// ==============================================================================
|
|
203
|
+
// Utilities
|
|
204
|
+
// ==============================================================================
|
|
205
|
+
async waitForUserOperationReceipt(userOpHash, timeout = 30000) {
|
|
206
|
+
console.log(`Waiting for UserOperation receipt...`);
|
|
207
|
+
const startTime = Date.now();
|
|
208
|
+
while (Date.now() - startTime < timeout) {
|
|
209
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
210
|
+
// In a real implementation, you'd query the bundler for receipt
|
|
211
|
+
// For now, we'll return a basic receipt structure
|
|
212
|
+
console.log("Checking for receipt...");
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
userOpHash,
|
|
216
|
+
success: true,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
async fundAccount(amount, fromPrivateKey) {
|
|
220
|
+
if (!this.smartAccount) {
|
|
221
|
+
throw new Error("Smart account not connected");
|
|
222
|
+
}
|
|
223
|
+
const signer = privateKeyToAccount(fromPrivateKey);
|
|
224
|
+
const client = createWalletClient({
|
|
225
|
+
account: signer,
|
|
226
|
+
chain: this.config.chain,
|
|
227
|
+
transport: http(this.config.rpcUrl),
|
|
228
|
+
});
|
|
229
|
+
console.log(`Funding account with ${amount} wei...`);
|
|
230
|
+
const hash = await client.sendTransaction({
|
|
231
|
+
to: this.smartAccount.address,
|
|
232
|
+
value: amount,
|
|
233
|
+
});
|
|
234
|
+
console.log(`ā
Funded: ${hash}`);
|
|
235
|
+
return hash;
|
|
236
|
+
}
|
|
237
|
+
// ==============================================================================
|
|
238
|
+
// Batch Operations
|
|
239
|
+
// ==============================================================================
|
|
240
|
+
async sendBatchUserOperations(operations) {
|
|
241
|
+
const results = [];
|
|
242
|
+
for (const op of operations) {
|
|
243
|
+
const hash = await this.sendUserOperation(op);
|
|
244
|
+
results.push(hash);
|
|
245
|
+
}
|
|
246
|
+
return results;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// ==============================================================================
|
|
250
|
+
// Helper Functions
|
|
251
|
+
// ==============================================================================
|
|
252
|
+
export function createDagAAClient(config) {
|
|
253
|
+
return new DagAAClient(config);
|
|
254
|
+
}
|
|
255
|
+
export function parseDAG(amount) {
|
|
256
|
+
return parseEther(amount);
|
|
257
|
+
}
|
|
258
|
+
// ==============================================================================
|
|
259
|
+
// Export Types
|
|
260
|
+
// ==============================================================================
|
|
261
|
+
// export type {
|
|
262
|
+
// DagAAConfig,
|
|
263
|
+
// SmartAccountConfig,
|
|
264
|
+
// SendUserOperationParams,
|
|
265
|
+
// UserOperationReceipt,
|
|
266
|
+
// };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineChain } from "viem";
|
|
2
|
+
const awakening_ = defineChain({
|
|
3
|
+
id: 1043,
|
|
4
|
+
name: "Awakening Testnet",
|
|
5
|
+
nativeCurrency: { decimals: 18, name: "Dag", symbol: "DAG" },
|
|
6
|
+
rpcUrls: { default: { http: ["https://public-bdag.nownodes.io"] } },
|
|
7
|
+
blockExplorers: {
|
|
8
|
+
default: { name: "Explorer", url: "https://awakening.bdagscan.com/" },
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
export const awakening = {
|
|
12
|
+
bundler_rpc: "http://0.0.0.0:3000/",
|
|
13
|
+
chain_config: awakening_,
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createDagAAClient, parseDAG } from "../clients/actions/main";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dag-kit/kit",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"author": "Abstract",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"private": false,
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "./dist/esm/exports/index.js",
|
|
10
|
+
"module": "./dist/esm/exports/index.js",
|
|
11
|
+
"types": "./dist/types/exports/index.d.ts",
|
|
12
|
+
"typings": "./dist/types/exports/index.d.ts",
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src/**/*.ts",
|
|
17
|
+
"package.json",
|
|
18
|
+
"!dist/**/*.tsbuildinfo",
|
|
19
|
+
"!vitest.config.ts",
|
|
20
|
+
"!.env",
|
|
21
|
+
"!src/**/*.test.ts",
|
|
22
|
+
"!src/**/*.test-d.ts",
|
|
23
|
+
"!src/__tests__/**/*"
|
|
24
|
+
],
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./dist/types/exports/index.d.ts",
|
|
28
|
+
"require": "./dist/esm/exports/index.js",
|
|
29
|
+
"import": "./dist/esm/exports/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./experimental": {
|
|
32
|
+
"types": "./dist/types/exports/experimental.d.ts",
|
|
33
|
+
"import": "./dist/esm/exports/experimental.js",
|
|
34
|
+
"default": "./dist/esm/exports/experimental.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"dotenv": "^16.6.1",
|
|
40
|
+
"permissionless": "^0.2.0",
|
|
41
|
+
"viem": "^2.20.0"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/node": "^20.11.10",
|
|
45
|
+
"tsx": "^3.13.0"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public",
|
|
49
|
+
"registry": "https://registry.npmjs.org/"
|
|
50
|
+
},
|
|
51
|
+
"repository": {
|
|
52
|
+
"type": "git",
|
|
53
|
+
"url": "git+https://github.com:Ayodeji63/blockdag-sdk.git"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/alchemyplatform/aa-sdk/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/alchemyplatform/aa-sdk#readme",
|
|
59
|
+
"scripts": {
|
|
60
|
+
"prebuild": "tsx ./inject-version.ts",
|
|
61
|
+
"build": "yarn clean && yarn build:esm && yarn build:types",
|
|
62
|
+
"build:esm": "tsc --project tsconfig.build.json --outDir ./dist/esm",
|
|
63
|
+
"build:types": "tsc --project tsconfig.build.json --declarationDir ./dist/types --emitDeclarationOnly --declaration --declarationMap",
|
|
64
|
+
"clean": "rm -rf ./dist",
|
|
65
|
+
"test:e2e": "bun test ./src/**/*.e2e.test.*"
|
|
66
|
+
}
|
|
67
|
+
}
|