@develit-services/blockchain 0.8.2 → 0.8.3

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 +88 -82
  12. package/dist/export/workflows.mjs +83 -77
  13. package/dist/shared/{blockchain.5Ld6uEay.d.ts → blockchain.7cRY-udH.d.ts} +1 -1
  14. package/dist/shared/blockchain.BUbQBxqd.cjs +335 -0
  15. package/dist/shared/blockchain.BhDiNGPI.mjs +332 -0
  16. package/dist/shared/{blockchain.DTJULMBV.mjs → blockchain.CKh8Fs7w.mjs} +12 -1
  17. package/dist/shared/{blockchain.CtIjPvX8.d.cts → blockchain.CaPQzwns.d.cts} +1 -1
  18. package/dist/shared/blockchain.CbmnjjFl.cjs +70 -0
  19. package/dist/shared/{blockchain.BBjLLe8v.cjs → blockchain.Cjq9eH7Z.cjs} +13 -0
  20. package/dist/shared/{blockchain.DZbyq0JM.d.mts → blockchain.CvNI0YTF.d.mts} +1 -1
  21. package/dist/shared/blockchain.DUhjXgba.d.cts +1107 -0
  22. package/dist/shared/blockchain.DUhjXgba.d.mts +1107 -0
  23. package/dist/shared/blockchain.DUhjXgba.d.ts +1107 -0
  24. package/dist/shared/blockchain._nv3VxNA.mjs +64 -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 +1 -1
  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,38 +1,57 @@
1
1
  'use strict';
2
2
 
3
3
  const backendSdk = require('@develit-io/backend-sdk');
4
- const drizzle = require('../shared/blockchain.DN735AwB.cjs');
4
+ const blockchain = require('../shared/blockchain.BUbQBxqd.cjs');
5
5
  const drizzleOrm = require('drizzle-orm');
6
6
  const cloudflare_workers = require('cloudflare:workers');
7
7
  const cloudflare_workflows = require('cloudflare:workflows');
8
8
  const d1 = require('drizzle-orm/d1');
9
- const viem = require('viem');
10
- const chains = require('viem/chains');
11
- require('../shared/blockchain.BBvwu2_7.cjs');
9
+ require('../shared/blockchain.CbmnjjFl.cjs');
12
10
  require('drizzle-orm/sqlite-core');
11
+ require('../shared/blockchain.Cjq9eH7Z.cjs');
12
+ require('zod');
13
+ require('viem');
14
+ require('viem/accounts');
15
+
16
+ const updateAddressLastSyncBlockCommand = (db, {
17
+ lastSyncBlock,
18
+ addressId
19
+ }) => {
20
+ const command = db.update(blockchain.tables.address).set({
21
+ lastSyncBlock
22
+ }).where(drizzleOrm.eq(blockchain.tables.address.id, addressId)).returning();
23
+ return {
24
+ command
25
+ };
26
+ };
13
27
 
14
28
  const updateAddressLastSyncCommand = (db, {
15
29
  lastSyncAt,
16
30
  addressId,
17
31
  lastSyncMetadata
18
32
  }) => {
19
- const command = db.update(drizzle.tables.address).set({
33
+ const command = db.update(blockchain.tables.address).set({
20
34
  lastSyncAt,
21
35
  lastSyncMetadata
22
- }).where(drizzleOrm.eq(drizzle.tables.address.id, addressId)).returning();
36
+ }).where(drizzleOrm.eq(blockchain.tables.address.id, addressId)).returning();
23
37
  return {
24
38
  command
25
39
  };
26
40
  };
27
41
 
28
42
  const getAddressById = async (db, id) => {
29
- const address = await db.select().from(drizzle.tables.address).where(drizzleOrm.eq(drizzle.tables.address.id, id)).get();
43
+ const address = await db.select().from(blockchain.tables.address).where(drizzleOrm.eq(blockchain.tables.address.id, id)).get();
30
44
  return address;
31
45
  };
32
46
 
47
+ const getContractAddresses = async (db, { connector }) => {
48
+ const addresses = await db.select().from(blockchain.tables.tokens).where(drizzleOrm.eq(blockchain.tables.tokens.connector, connector)).all();
49
+ return addresses;
50
+ };
51
+
33
52
  const createTransactionCommand = (db, { transaction }) => {
34
53
  const id = backendSdk.uuidv4();
35
- const command = db.insert(drizzle.tables.transaction).values({ ...transaction, id }).returning();
54
+ const command = db.insert(blockchain.tables.transaction).values({ ...transaction, id }).returning();
36
55
  return { command };
37
56
  };
38
57
 
@@ -48,7 +67,7 @@ function pushToQueue(queue, message) {
48
67
  class BlockchainSyncAddressTransactions extends cloudflare_workers.WorkflowEntrypoint {
49
68
  async run(event, step) {
50
69
  const { addressId } = event.payload;
51
- const db = d1.drizzle(this.env.BLOCKCHAIN_D1, { schema: drizzle.tables });
70
+ const db = d1.drizzle(this.env.BLOCKCHAIN_D1, { schema: blockchain.tables });
52
71
  if (!addressId) {
53
72
  throw new cloudflare_workflows.NonRetryableError(`Haven't obtained addressId to load.`);
54
73
  }
@@ -64,7 +83,9 @@ class BlockchainSyncAddressTransactions extends cloudflare_workers.WorkflowEntry
64
83
  return address2;
65
84
  });
66
85
  if (!address.lastSyncAt) {
67
- throw new Error(`lastSyncedAt is not set for address: ${address}`);
86
+ throw new cloudflare_workflows.NonRetryableError(
87
+ `lastSyncedAt is not set for address: ${address}`
88
+ );
68
89
  }
69
90
  const transactions = await step.do(
70
91
  "fetch address transactions",
@@ -73,86 +94,63 @@ class BlockchainSyncAddressTransactions extends cloudflare_workers.WorkflowEntry
73
94
  timeout: "30 seconds"
74
95
  },
75
96
  async () => {
76
- const rpcUrl = (await this.env.SECRETS_STORE.get({
77
- secretName: "BLOCKCHAIN_SERVICE_RPC_URL"
78
- })).data?.secretValue || "";
79
- const client = viem.createPublicClient({
80
- chain: chains.gnosisChiado,
81
- transport: viem.http(rpcUrl)
97
+ const tokens = await getContractAddresses(db, {
98
+ connector: address.connector
82
99
  });
83
- const currentBlock = await client.getBlockNumber();
84
- const estimatedBlocksPerInterval = Math.ceil(
85
- address.syncIntervalS * 1.5 / 5
86
- );
87
- const blocksToScan = Math.min(estimatedBlocksPerInterval, 1e3);
88
- const startBlock = currentBlock - BigInt(blocksToScan);
89
- const endBlock = currentBlock;
90
- const lastSyncedTimestamp = address.lastSyncAt || 0;
91
- const allTransactions = [];
92
- for (let blockNum = startBlock; blockNum <= endBlock; blockNum++) {
93
- const block = await client.getBlock({
94
- blockNumber: blockNum,
95
- includeTransactions: true
96
- });
97
- const blockTimestamp = Number(block.timestamp);
98
- const lastSyncedTimestampNum = typeof lastSyncedTimestamp === "number" ? lastSyncedTimestamp : Number(lastSyncedTimestamp);
99
- if (blockTimestamp <= lastSyncedTimestampNum) {
100
- continue;
101
- }
102
- for (const tx of block.transactions) {
103
- if (typeof tx === "string" || !tx.to) continue;
104
- if (tx.from.toLowerCase() === address.number.toLowerCase()) {
105
- const receipt = await client.getTransactionReceipt({
106
- hash: tx.hash
107
- });
108
- allTransactions.push({
109
- hash: tx.hash,
110
- from: tx.from,
111
- to: tx.to,
112
- value: tx.value.toString(),
113
- blockNumber: block.number.toString(),
114
- blockHash: block.hash,
115
- gasUsed: receipt.gasUsed.toString(),
116
- gasPrice: tx.gasPrice?.toString() ?? "",
117
- timestamp: blockTimestamp,
118
- status: receipt.status
119
- });
120
- }
121
- }
100
+ if (!tokens || tokens.length === 0) {
101
+ throw new cloudflare_workflows.NonRetryableError(
102
+ `No contract addresses found for connector: ${address.connector}`
103
+ );
122
104
  }
123
- return allTransactions;
105
+ const connector = await blockchain.initiateConnector({
106
+ chain: address.connector,
107
+ env: this.env,
108
+ tokens,
109
+ connectedAddresses: [
110
+ {
111
+ id: address.id,
112
+ number: address.number,
113
+ connector: address.connector
114
+ }
115
+ ]
116
+ });
117
+ return await connector.getAllAddressTransactions({
118
+ address: address.number,
119
+ filter: { fromBlock: address.lastSyncBlock }
120
+ });
124
121
  }
125
122
  );
126
- if (transactions.length > 0) {
123
+ if (transactions.transactions.length > 0) {
127
124
  await step.do(
128
125
  "process new transactions and update lastSyncAt",
129
126
  async () => {
130
- const createCommands = transactions.map(
127
+ const createCommands = transactions.transactions.map(
131
128
  (tx) => createTransactionCommand(db, { transaction: tx }).command
132
129
  );
133
- const eventsToEmit = transactions.map(
134
- (tx) => ({
135
- eventType: "BLOCKCHAIN_TRANSACTION",
136
- blockchainTransaction: {
137
- address: address.number,
138
- hash: tx.hash,
139
- from: tx.from,
140
- to: tx.to,
141
- value: tx.value,
142
- blockNumber: tx.blockNumber,
143
- blockHash: tx.blockHash,
144
- gasUsed: tx.gasUsed,
145
- gasPrice: tx.gasPrice,
146
- timestamp: tx.timestamp,
147
- status: tx.status
148
- },
149
- metadata: {
150
- correlationId: backendSdk.uuidv4(),
151
- entityId: backendSdk.uuidv4(),
152
- timestamp: (/* @__PURE__ */ new Date()).toDateString()
153
- }
154
- })
155
- );
130
+ const eventsToEmit = transactions.transactions.map((tx) => ({
131
+ eventType: "BLOCKCHAIN_TRANSACTION",
132
+ blockchainTransaction: {
133
+ address: address.number,
134
+ hash: tx.hash,
135
+ from: tx.from,
136
+ to: tx.to,
137
+ value: tx.value,
138
+ blockNumber: tx.blockNumber,
139
+ blockHash: tx.blockHash,
140
+ gasUsed: tx.gasUsed,
141
+ gasPrice: tx.gasPrice,
142
+ timestamp: tx.timestamp,
143
+ status: tx.status,
144
+ decimals: tx.decimals,
145
+ connector: address.connector,
146
+ ticker: tx.ticker
147
+ },
148
+ metadata: {
149
+ correlationId: backendSdk.uuidv4(),
150
+ entityId: backendSdk.uuidv4(),
151
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
152
+ }
153
+ }));
156
154
  const lastSyncMetadata = {
157
155
  eventsEmitted: eventsToEmit.length
158
156
  };
@@ -161,9 +159,17 @@ class BlockchainSyncAddressTransactions extends cloudflare_workers.WorkflowEntry
161
159
  lastSyncAt: now,
162
160
  lastSyncMetadata
163
161
  }).command;
162
+ const updateLastSyncBlockCommand = updateAddressLastSyncBlockCommand(db, {
163
+ addressId: address.id,
164
+ lastSyncBlock: transactions.latestBlock
165
+ }).command;
164
166
  if (eventsToEmit.length) {
165
167
  await db.batch(
166
- backendSdk.asNonEmpty([updateLastSyncCommand, ...createCommands])
168
+ backendSdk.asNonEmpty([
169
+ updateLastSyncCommand,
170
+ updateLastSyncBlockCommand,
171
+ ...createCommands
172
+ ])
167
173
  );
168
174
  await pushToQueue(
169
175
  this.env.QUEUE_BUS_QUEUE,
@@ -1,13 +1,27 @@
1
1
  import { uuidv4, asNonEmpty } from '@develit-io/backend-sdk';
2
- import { t as tables } from '../shared/blockchain.0tUJ62WT.mjs';
2
+ import { t as tables, i as initiateConnector } from '../shared/blockchain.BhDiNGPI.mjs';
3
3
  import { eq } from 'drizzle-orm';
4
4
  import { WorkflowEntrypoint } from 'cloudflare:workers';
5
5
  import { NonRetryableError } from 'cloudflare:workflows';
6
6
  import { drizzle } from 'drizzle-orm/d1';
7
- import { createPublicClient, http } from 'viem';
8
- import { gnosisChiado } from 'viem/chains';
9
- import '../shared/blockchain._wwKu1qP.mjs';
7
+ import '../shared/blockchain._nv3VxNA.mjs';
10
8
  import 'drizzle-orm/sqlite-core';
9
+ import '../shared/blockchain.CKh8Fs7w.mjs';
10
+ import 'zod';
11
+ import 'viem';
12
+ import 'viem/accounts';
13
+
14
+ const updateAddressLastSyncBlockCommand = (db, {
15
+ lastSyncBlock,
16
+ addressId
17
+ }) => {
18
+ const command = db.update(tables.address).set({
19
+ lastSyncBlock
20
+ }).where(eq(tables.address.id, addressId)).returning();
21
+ return {
22
+ command
23
+ };
24
+ };
11
25
 
12
26
  const updateAddressLastSyncCommand = (db, {
13
27
  lastSyncAt,
@@ -28,6 +42,11 @@ const getAddressById = async (db, id) => {
28
42
  return address;
29
43
  };
30
44
 
45
+ const getContractAddresses = async (db, { connector }) => {
46
+ const addresses = await db.select().from(tables.tokens).where(eq(tables.tokens.connector, connector)).all();
47
+ return addresses;
48
+ };
49
+
31
50
  const createTransactionCommand = (db, { transaction }) => {
32
51
  const id = uuidv4();
33
52
  const command = db.insert(tables.transaction).values({ ...transaction, id }).returning();
@@ -62,7 +81,9 @@ class BlockchainSyncAddressTransactions extends WorkflowEntrypoint {
62
81
  return address2;
63
82
  });
64
83
  if (!address.lastSyncAt) {
65
- throw new Error(`lastSyncedAt is not set for address: ${address}`);
84
+ throw new NonRetryableError(
85
+ `lastSyncedAt is not set for address: ${address}`
86
+ );
66
87
  }
67
88
  const transactions = await step.do(
68
89
  "fetch address transactions",
@@ -71,86 +92,63 @@ class BlockchainSyncAddressTransactions extends WorkflowEntrypoint {
71
92
  timeout: "30 seconds"
72
93
  },
73
94
  async () => {
74
- const rpcUrl = (await this.env.SECRETS_STORE.get({
75
- secretName: "BLOCKCHAIN_SERVICE_RPC_URL"
76
- })).data?.secretValue || "";
77
- const client = createPublicClient({
78
- chain: gnosisChiado,
79
- transport: http(rpcUrl)
95
+ const tokens = await getContractAddresses(db, {
96
+ connector: address.connector
80
97
  });
81
- const currentBlock = await client.getBlockNumber();
82
- const estimatedBlocksPerInterval = Math.ceil(
83
- address.syncIntervalS * 1.5 / 5
84
- );
85
- const blocksToScan = Math.min(estimatedBlocksPerInterval, 1e3);
86
- const startBlock = currentBlock - BigInt(blocksToScan);
87
- const endBlock = currentBlock;
88
- const lastSyncedTimestamp = address.lastSyncAt || 0;
89
- const allTransactions = [];
90
- for (let blockNum = startBlock; blockNum <= endBlock; blockNum++) {
91
- const block = await client.getBlock({
92
- blockNumber: blockNum,
93
- includeTransactions: true
94
- });
95
- const blockTimestamp = Number(block.timestamp);
96
- const lastSyncedTimestampNum = typeof lastSyncedTimestamp === "number" ? lastSyncedTimestamp : Number(lastSyncedTimestamp);
97
- if (blockTimestamp <= lastSyncedTimestampNum) {
98
- continue;
99
- }
100
- for (const tx of block.transactions) {
101
- if (typeof tx === "string" || !tx.to) continue;
102
- if (tx.from.toLowerCase() === address.number.toLowerCase()) {
103
- const receipt = await client.getTransactionReceipt({
104
- hash: tx.hash
105
- });
106
- allTransactions.push({
107
- hash: tx.hash,
108
- from: tx.from,
109
- to: tx.to,
110
- value: tx.value.toString(),
111
- blockNumber: block.number.toString(),
112
- blockHash: block.hash,
113
- gasUsed: receipt.gasUsed.toString(),
114
- gasPrice: tx.gasPrice?.toString() ?? "",
115
- timestamp: blockTimestamp,
116
- status: receipt.status
117
- });
118
- }
119
- }
98
+ if (!tokens || tokens.length === 0) {
99
+ throw new NonRetryableError(
100
+ `No contract addresses found for connector: ${address.connector}`
101
+ );
120
102
  }
121
- return allTransactions;
103
+ const connector = await initiateConnector({
104
+ chain: address.connector,
105
+ env: this.env,
106
+ tokens,
107
+ connectedAddresses: [
108
+ {
109
+ id: address.id,
110
+ number: address.number,
111
+ connector: address.connector
112
+ }
113
+ ]
114
+ });
115
+ return await connector.getAllAddressTransactions({
116
+ address: address.number,
117
+ filter: { fromBlock: address.lastSyncBlock }
118
+ });
122
119
  }
123
120
  );
124
- if (transactions.length > 0) {
121
+ if (transactions.transactions.length > 0) {
125
122
  await step.do(
126
123
  "process new transactions and update lastSyncAt",
127
124
  async () => {
128
- const createCommands = transactions.map(
125
+ const createCommands = transactions.transactions.map(
129
126
  (tx) => createTransactionCommand(db, { transaction: tx }).command
130
127
  );
131
- const eventsToEmit = transactions.map(
132
- (tx) => ({
133
- eventType: "BLOCKCHAIN_TRANSACTION",
134
- blockchainTransaction: {
135
- address: address.number,
136
- hash: tx.hash,
137
- from: tx.from,
138
- to: tx.to,
139
- value: tx.value,
140
- blockNumber: tx.blockNumber,
141
- blockHash: tx.blockHash,
142
- gasUsed: tx.gasUsed,
143
- gasPrice: tx.gasPrice,
144
- timestamp: tx.timestamp,
145
- status: tx.status
146
- },
147
- metadata: {
148
- correlationId: uuidv4(),
149
- entityId: uuidv4(),
150
- timestamp: (/* @__PURE__ */ new Date()).toDateString()
151
- }
152
- })
153
- );
128
+ const eventsToEmit = transactions.transactions.map((tx) => ({
129
+ eventType: "BLOCKCHAIN_TRANSACTION",
130
+ blockchainTransaction: {
131
+ address: address.number,
132
+ hash: tx.hash,
133
+ from: tx.from,
134
+ to: tx.to,
135
+ value: tx.value,
136
+ blockNumber: tx.blockNumber,
137
+ blockHash: tx.blockHash,
138
+ gasUsed: tx.gasUsed,
139
+ gasPrice: tx.gasPrice,
140
+ timestamp: tx.timestamp,
141
+ status: tx.status,
142
+ decimals: tx.decimals,
143
+ connector: address.connector,
144
+ ticker: tx.ticker
145
+ },
146
+ metadata: {
147
+ correlationId: uuidv4(),
148
+ entityId: uuidv4(),
149
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
150
+ }
151
+ }));
154
152
  const lastSyncMetadata = {
155
153
  eventsEmitted: eventsToEmit.length
156
154
  };
@@ -159,9 +157,17 @@ class BlockchainSyncAddressTransactions extends WorkflowEntrypoint {
159
157
  lastSyncAt: now,
160
158
  lastSyncMetadata
161
159
  }).command;
160
+ const updateLastSyncBlockCommand = updateAddressLastSyncBlockCommand(db, {
161
+ addressId: address.id,
162
+ lastSyncBlock: transactions.latestBlock
163
+ }).command;
162
164
  if (eventsToEmit.length) {
163
165
  await db.batch(
164
- asNonEmpty([updateLastSyncCommand, ...createCommands])
166
+ asNonEmpty([
167
+ updateLastSyncCommand,
168
+ updateLastSyncBlockCommand,
169
+ ...createCommands
170
+ ])
165
171
  );
166
172
  await pushToQueue(
167
173
  this.env.QUEUE_BUS_QUEUE,
@@ -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<{