@develit-services/blockchain 0.8.2 → 0.8.4

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.
Files changed (37) hide show
  1. package/dist/database/schema.cjs +5 -1
  2. package/dist/database/schema.d.cts +1 -1
  3. package/dist/database/schema.d.mts +1 -1
  4. package/dist/database/schema.d.ts +1 -1
  5. package/dist/database/schema.mjs +3 -1
  6. package/dist/export/worker.cjs +20 -625
  7. package/dist/export/worker.d.cts +2 -2
  8. package/dist/export/worker.d.mts +2 -2
  9. package/dist/export/worker.d.ts +2 -2
  10. package/dist/export/worker.mjs +20 -625
  11. package/dist/export/workflows.cjs +100 -85
  12. package/dist/export/workflows.mjs +96 -81
  13. package/dist/shared/blockchain.BKGlFbOW.mjs +68 -0
  14. package/dist/shared/{blockchain.CtIjPvX8.d.cts → blockchain.Br6esGv4.d.cts} +3 -3
  15. package/dist/shared/{blockchain.DTJULMBV.mjs → blockchain.CKh8Fs7w.mjs} +12 -1
  16. package/dist/shared/{blockchain.BBjLLe8v.cjs → blockchain.Cjq9eH7Z.cjs} +13 -0
  17. package/dist/shared/blockchain.DUhjXgba.d.cts +1107 -0
  18. package/dist/shared/blockchain.DUhjXgba.d.mts +1107 -0
  19. package/dist/shared/blockchain.DUhjXgba.d.ts +1107 -0
  20. package/dist/shared/{blockchain.DZbyq0JM.d.mts → blockchain.DcWSUM60.d.mts} +3 -3
  21. package/dist/shared/{blockchain.5Ld6uEay.d.ts → blockchain.DurPotrN.d.ts} +3 -3
  22. package/dist/shared/blockchain.JBv4ipVR.cjs +335 -0
  23. package/dist/shared/blockchain.ZJPECySM.cjs +74 -0
  24. package/dist/shared/blockchain.wsLSmIaf.mjs +332 -0
  25. package/dist/types.cjs +3 -1
  26. package/dist/types.d.cts +12 -4
  27. package/dist/types.d.mts +12 -4
  28. package/dist/types.d.ts +12 -4
  29. package/dist/types.mjs +1 -1
  30. package/package.json +2 -2
  31. package/dist/shared/blockchain.0tUJ62WT.mjs +0 -6
  32. package/dist/shared/blockchain.BBvwu2_7.cjs +0 -39
  33. package/dist/shared/blockchain.Cx60lJ0c.d.cts +0 -566
  34. package/dist/shared/blockchain.Cx60lJ0c.d.mts +0 -566
  35. package/dist/shared/blockchain.Cx60lJ0c.d.ts +0 -566
  36. package/dist/shared/blockchain.DN735AwB.cjs +0 -8
  37. package/dist/shared/blockchain._wwKu1qP.mjs +0 -35
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { s as schema } from './blockchain.Cx60lJ0c.mjs';
2
+ import { s as schema } from './blockchain.DUhjXgba.mjs';
3
3
 
4
4
  declare const getBlockInputSchema: z.ZodObject<{
5
5
  chain: z.ZodEnum<{
@@ -12,9 +12,9 @@ declare const getBlockInputSchema: z.ZodObject<{
12
12
  SCROLL: "SCROLL";
13
13
  }>;
14
14
  blockTag: z.ZodOptional<z.ZodEnum<{
15
- pending: "pending";
16
15
  latest: "latest";
17
16
  earliest: "earliest";
17
+ pending: "pending";
18
18
  safe: "safe";
19
19
  finalized: "finalized";
20
20
  }>>;
@@ -93,9 +93,9 @@ declare const getTransactionOutputSchema: z.ZodObject<{
93
93
  nonce: z.ZodNumber;
94
94
  transactionIndex: z.ZodNullable<z.ZodNumber>;
95
95
  status: z.ZodEnum<{
96
+ pending: "pending";
96
97
  success: "success";
97
98
  reverted: "reverted";
98
- pending: "pending";
99
99
  }>;
100
100
  gasUsed: z.ZodNullable<z.ZodString>;
101
101
  timestamp: z.ZodNullable<z.ZodNumber>;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { s as schema } from './blockchain.Cx60lJ0c.js';
2
+ import { s as schema } from './blockchain.DUhjXgba.js';
3
3
 
4
4
  declare const getBlockInputSchema: z.ZodObject<{
5
5
  chain: z.ZodEnum<{
@@ -12,9 +12,9 @@ declare const getBlockInputSchema: z.ZodObject<{
12
12
  SCROLL: "SCROLL";
13
13
  }>;
14
14
  blockTag: z.ZodOptional<z.ZodEnum<{
15
- pending: "pending";
16
15
  latest: "latest";
17
16
  earliest: "earliest";
17
+ pending: "pending";
18
18
  safe: "safe";
19
19
  finalized: "finalized";
20
20
  }>>;
@@ -93,9 +93,9 @@ declare const getTransactionOutputSchema: z.ZodObject<{
93
93
  nonce: z.ZodNumber;
94
94
  transactionIndex: z.ZodNullable<z.ZodNumber>;
95
95
  status: z.ZodEnum<{
96
+ pending: "pending";
96
97
  success: "success";
97
98
  reverted: "reverted";
98
- pending: "pending";
99
99
  }>;
100
100
  gasUsed: z.ZodNullable<z.ZodString>;
101
101
  timestamp: z.ZodNullable<z.ZodNumber>;
@@ -0,0 +1,335 @@
1
+ 'use strict';
2
+
3
+ const database_schema = require('./blockchain.ZJPECySM.cjs');
4
+ require('drizzle-orm');
5
+ const backendSdk = require('@develit-io/backend-sdk');
6
+ const viem = require('viem');
7
+ const accounts = require('viem/accounts');
8
+
9
+ const tables = database_schema.schema;
10
+
11
+ class IBlockchainConnector {
12
+ }
13
+
14
+ const TRANSFER_EVENT_ABI = [
15
+ {
16
+ type: "event",
17
+ name: "Transfer",
18
+ inputs: [
19
+ { indexed: true, name: "from", type: "address" },
20
+ { indexed: true, name: "to", type: "address" },
21
+ { indexed: false, name: "value", type: "uint256" }
22
+ ]
23
+ }
24
+ ];
25
+ const ERC20_TRANSFER_ABI = [
26
+ {
27
+ type: "function",
28
+ name: "transfer",
29
+ inputs: [
30
+ { name: "to", type: "address" },
31
+ { name: "amount", type: "uint256" }
32
+ ],
33
+ outputs: [{ name: "", type: "bool" }],
34
+ stateMutability: "nonpayable"
35
+ }
36
+ ];
37
+ class EvmConnector extends IBlockchainConnector {
38
+ constructor(config) {
39
+ super();
40
+ this.client = null;
41
+ this.rpcUrl = config.RPC_URL;
42
+ this.tokens = config.tokens;
43
+ this.connectedAddresses = config.connectedAddresses;
44
+ this.resolveCredentials = config.resolveCredentials;
45
+ }
46
+ createClient() {
47
+ if (!this.client) {
48
+ this.client = viem.createPublicClient({
49
+ transport: viem.http(this.rpcUrl)
50
+ });
51
+ }
52
+ return this.client;
53
+ }
54
+ async getTransaction(txHash) {
55
+ const client = this.createClient();
56
+ const [tx, txError] = await backendSdk.useResult(
57
+ client.getTransaction({ hash: txHash })
58
+ );
59
+ if (txError || !tx) {
60
+ throw backendSdk.createInternalError(txError);
61
+ }
62
+ let status = "pending";
63
+ let gasUsed = null;
64
+ let timestamp = null;
65
+ if (tx.blockNumber) {
66
+ const [receipt, receiptError] = await backendSdk.useResult(
67
+ client.getTransactionReceipt({ hash: txHash })
68
+ );
69
+ if (receiptError || !receipt) {
70
+ throw backendSdk.createInternalError(receiptError);
71
+ }
72
+ const [block, blockError] = await backendSdk.useResult(
73
+ client.getBlock({ blockNumber: tx.blockNumber })
74
+ );
75
+ if (blockError || !block) {
76
+ throw backendSdk.createInternalError(blockError);
77
+ }
78
+ status = receipt.status === "success" ? "success" : "reverted";
79
+ gasUsed = receipt.gasUsed.toString();
80
+ timestamp = Number(block.timestamp) * 1e3;
81
+ }
82
+ return {
83
+ hash: tx.hash,
84
+ from: tx.from,
85
+ to: tx.to,
86
+ value: tx.value.toString(),
87
+ blockNumber: tx.blockNumber?.toString() ?? null,
88
+ blockHash: tx.blockHash ?? null,
89
+ gasPrice: tx.gasPrice?.toString() ?? null,
90
+ gas: tx.gas.toString(),
91
+ nonce: tx.nonce,
92
+ transactionIndex: tx.transactionIndex,
93
+ status,
94
+ gasUsed,
95
+ timestamp
96
+ };
97
+ }
98
+ async getTransactionReceipt(txHash) {
99
+ const client = this.createClient();
100
+ const [receipt, error] = await backendSdk.useResult(
101
+ client.getTransactionReceipt({ hash: txHash })
102
+ );
103
+ if (error || !receipt) {
104
+ throw backendSdk.createInternalError(error);
105
+ }
106
+ return receipt;
107
+ }
108
+ async getBlock({
109
+ blockHash,
110
+ blockNumber,
111
+ blockTag
112
+ }) {
113
+ const client = this.createClient();
114
+ const [block, error] = await backendSdk.useResult(
115
+ blockHash !== void 0 ? client.getBlock({ blockHash }) : blockNumber !== void 0 ? client.getBlock({ blockNumber }) : client.getBlock({ blockTag: blockTag ?? "finalized" })
116
+ );
117
+ if (error || !block) {
118
+ throw error;
119
+ }
120
+ return block;
121
+ }
122
+ async getAllAddressTransactions({
123
+ address,
124
+ filter
125
+ }) {
126
+ const client = this.createClient();
127
+ const latestBlock = await client.getBlockNumber();
128
+ const transactions = [];
129
+ const allTransactionsFromContracts = await Promise.all(
130
+ this.tokens.map(async (token) => {
131
+ const events = await client.getContractEvents({
132
+ abi: TRANSFER_EVENT_ABI,
133
+ address: token.smartContractAddress,
134
+ eventName: "Transfer",
135
+ args: {
136
+ to: address
137
+ },
138
+ fromBlock: filter.fromBlock ?? latestBlock - 900n,
139
+ toBlock: "latest"
140
+ });
141
+ return { events, token };
142
+ })
143
+ );
144
+ for (const { events, token } of allTransactionsFromContracts) {
145
+ for (const tx of events) {
146
+ const [receipt, block] = await Promise.all([
147
+ client.getTransactionReceipt({ hash: tx.transactionHash }),
148
+ client.getBlock({ blockNumber: tx.blockNumber })
149
+ ]);
150
+ transactions.push({
151
+ hash: tx.transactionHash,
152
+ from: tx.args.from ?? "",
153
+ to: tx.args.to ?? "",
154
+ value: (tx.args.value ?? 0n).toString(),
155
+ blockNumber: tx.blockNumber.toString(),
156
+ blockHash: tx.blockHash,
157
+ gasUsed: receipt.gasUsed.toString(),
158
+ gasPrice: receipt.effectiveGasPrice?.toString() ?? "",
159
+ timestamp: Number(block.timestamp),
160
+ status: receipt.status,
161
+ decimals: token.decimals,
162
+ connector: this.connectorKey,
163
+ ticker: token.ticker
164
+ });
165
+ }
166
+ }
167
+ return { transactions, latestBlock };
168
+ }
169
+ async sendTransaction({
170
+ from,
171
+ to,
172
+ value,
173
+ token
174
+ }) {
175
+ const address = this.connectedAddresses.find(
176
+ (a) => a.number.toLowerCase() === from.toLowerCase()
177
+ );
178
+ if (!address) {
179
+ throw backendSdk.createInternalError(null, {
180
+ message: `Address not found: ${from}`
181
+ });
182
+ }
183
+ if (!this.resolveCredentials) {
184
+ throw backendSdk.createInternalError(null, {
185
+ message: `Credentials resolver not provided`
186
+ });
187
+ }
188
+ const credentials = await this.resolveCredentials(address.id);
189
+ if (!credentials) {
190
+ throw backendSdk.createInternalError(null, {
191
+ message: `No private key found for address: ${from}`
192
+ });
193
+ }
194
+ const account = accounts.privateKeyToAccount(credentials.value);
195
+ const walletClient = viem.createWalletClient({
196
+ account,
197
+ transport: viem.http(this.rpcUrl)
198
+ });
199
+ let hash;
200
+ if (token) {
201
+ const data = viem.encodeFunctionData({
202
+ abi: ERC20_TRANSFER_ABI,
203
+ functionName: "transfer",
204
+ args: [to, viem.parseUnits(value, token.decimals)]
205
+ });
206
+ hash = await walletClient.sendTransaction({
207
+ chain: null,
208
+ to: token.smartContractAddress,
209
+ data
210
+ });
211
+ } else {
212
+ hash = await walletClient.sendTransaction({
213
+ chain: null,
214
+ to,
215
+ value: BigInt(value)
216
+ });
217
+ }
218
+ return { hash };
219
+ }
220
+ }
221
+
222
+ class ArbitrumConnector extends EvmConnector {
223
+ constructor(config) {
224
+ super(config);
225
+ this.connectorKey = "ARBITRUM";
226
+ }
227
+ }
228
+
229
+ class AvalancheConnector extends EvmConnector {
230
+ constructor(config) {
231
+ super(config);
232
+ this.connectorKey = "AVALANCHE";
233
+ }
234
+ }
235
+
236
+ class BaseConnector extends EvmConnector {
237
+ constructor(config) {
238
+ super(config);
239
+ this.connectorKey = "BASE";
240
+ }
241
+ }
242
+
243
+ class EthereumConnector extends EvmConnector {
244
+ constructor(config) {
245
+ super(config);
246
+ this.connectorKey = "ETHEREUM";
247
+ }
248
+ }
249
+
250
+ class GnosisConnector extends EvmConnector {
251
+ constructor(config) {
252
+ super(config);
253
+ this.connectorKey = "GNOSIS";
254
+ }
255
+ }
256
+
257
+ class OptimismConnector extends EvmConnector {
258
+ constructor(config) {
259
+ super(config);
260
+ this.connectorKey = "OPTIMISM";
261
+ }
262
+ }
263
+
264
+ class ScrollConnector extends EvmConnector {
265
+ constructor(config) {
266
+ super(config);
267
+ this.connectorKey = "SCROLL";
268
+ }
269
+ }
270
+
271
+ const initiateConnector = async ({
272
+ chain,
273
+ env,
274
+ tokens,
275
+ connectedAddresses,
276
+ resolveCredentials
277
+ }) => {
278
+ const getRpcUrl = async (secretName) => (await env.SECRETS_STORE.get({ secretName })).data?.secretValue || "";
279
+ switch (chain) {
280
+ case "ETHEREUM":
281
+ return new EthereumConnector({
282
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_ETHEREUM_RPC_URL"),
283
+ tokens,
284
+ connectedAddresses,
285
+ resolveCredentials
286
+ });
287
+ case "ARBITRUM":
288
+ return new ArbitrumConnector({
289
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_ARBITRUM_RPC_URL"),
290
+ tokens,
291
+ connectedAddresses,
292
+ resolveCredentials
293
+ });
294
+ case "AVALANCHE":
295
+ return new AvalancheConnector({
296
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_AVALANCHE_RPC_URL"),
297
+ tokens,
298
+ connectedAddresses,
299
+ resolveCredentials
300
+ });
301
+ case "BASE":
302
+ return new BaseConnector({
303
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_BASE_RPC_URL"),
304
+ tokens,
305
+ connectedAddresses,
306
+ resolveCredentials
307
+ });
308
+ case "GNOSIS":
309
+ return new GnosisConnector({
310
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_GNOSIS_RPC_URL"),
311
+ tokens,
312
+ connectedAddresses,
313
+ resolveCredentials
314
+ });
315
+ case "OPTIMISM":
316
+ return new OptimismConnector({
317
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_OPTIMISM_RPC_URL"),
318
+ tokens,
319
+ connectedAddresses,
320
+ resolveCredentials
321
+ });
322
+ case "SCROLL":
323
+ return new ScrollConnector({
324
+ RPC_URL: await getRpcUrl("BLOCKCHAIN_SERVICE_SCROLL_RPC_URL"),
325
+ tokens,
326
+ connectedAddresses,
327
+ resolveCredentials
328
+ });
329
+ default:
330
+ throw new Error(`Unsupported chain: ${chain}`);
331
+ }
332
+ };
333
+
334
+ exports.initiateConnector = initiateConnector;
335
+ exports.tables = tables;
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ const backendSdk = require('@develit-io/backend-sdk');
4
+ const sqliteCore = require('drizzle-orm/sqlite-core');
5
+ const syncAddress = require('./blockchain.Cjq9eH7Z.cjs');
6
+
7
+ const address = sqliteCore.sqliteTable("address", {
8
+ ...backendSdk.base,
9
+ number: sqliteCore.text("number").notNull(),
10
+ syncIntervalS: sqliteCore.integer("sync_interval_s").notNull().default(600),
11
+ lastSyncBlock: sqliteCore.blob("last_sync_block", { mode: "bigint" }),
12
+ lastSyncAt: sqliteCore.integer("last_sync_at", { mode: "timestamp_ms" }),
13
+ lastSyncMetadata: sqliteCore.text("last_sync_metadata", {
14
+ mode: "json"
15
+ }).$type(),
16
+ connector: sqliteCore.text("connector").$type()
17
+ });
18
+
19
+ const addressCredentials = sqliteCore.sqliteTable("address_credentials", {
20
+ ...backendSdk.base,
21
+ addressId: sqliteCore.text("address_id").references(() => address.id, { onDelete: "restrict", onUpdate: "cascade" }).notNull(),
22
+ connector: sqliteCore.text("connector", {
23
+ enum: syncAddress.CHAIN_KEYS
24
+ }).$type().notNull(),
25
+ type: sqliteCore.text("type", {
26
+ enum: syncAddress.CREDENTIALS_TYPES
27
+ }).$type().notNull(),
28
+ value: sqliteCore.text("value").notNull(),
29
+ expiresAt: sqliteCore.integer("expires_at", { mode: "timestamp_ms" })
30
+ });
31
+
32
+ const tokens = sqliteCore.sqliteTable("tokens", {
33
+ ...backendSdk.base,
34
+ smartContractAddress: sqliteCore.text("smart_contract_address").$type().notNull(),
35
+ connector: sqliteCore.text("connector").$type(),
36
+ ticker: sqliteCore.text("ticker").notNull(),
37
+ decimals: sqliteCore.integer("decimals").notNull(),
38
+ name: sqliteCore.text("name")
39
+ });
40
+
41
+ const transaction = sqliteCore.sqliteTable(
42
+ "transaction",
43
+ {
44
+ ...backendSdk.base,
45
+ hash: sqliteCore.text("hash"),
46
+ from: sqliteCore.text("from"),
47
+ to: sqliteCore.text("to"),
48
+ value: sqliteCore.text("value"),
49
+ blockNumber: sqliteCore.text("block_number"),
50
+ blockHash: sqliteCore.text("blockHash"),
51
+ gasUsed: sqliteCore.text("gasUsed"),
52
+ gasPrice: sqliteCore.text("gasPrice"),
53
+ timestamp: sqliteCore.integer("timestamp"),
54
+ status: sqliteCore.text("status"),
55
+ decimals: sqliteCore.integer("decimals"),
56
+ connector: sqliteCore.text("connector").$type(),
57
+ ticker: sqliteCore.text("ticker")
58
+ },
59
+ (t) => [sqliteCore.uniqueIndex("transaction_hash_unique").on(t.hash)]
60
+ );
61
+
62
+ const schema = {
63
+ __proto__: null,
64
+ address: address,
65
+ addressCredentials: addressCredentials,
66
+ tokens: tokens,
67
+ transaction: transaction
68
+ };
69
+
70
+ exports.address = address;
71
+ exports.addressCredentials = addressCredentials;
72
+ exports.schema = schema;
73
+ exports.tokens = tokens;
74
+ exports.transaction = transaction;