Skip to content

Commit 6a7bbc5

Browse files
author
Harshdev098
committed
feat(persistence-ethereum): Added support for erc1155
Signed-off-by: Harshdev098 <[email protected]>
1 parent 9b04d5e commit 6a7bbc5

File tree

11 files changed

+1809
-13
lines changed

11 files changed

+1809
-13
lines changed

packages/cactus-plugin-persistence-ethereum/src/main/json/contract-abi/ERC1155.json

Lines changed: 579 additions & 0 deletions
Large diffs are not rendered by default.

packages/cactus-plugin-persistence-ethereum/src/main/json/openapi.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
"schemas": {
1414
"TokenTypeV1": {
1515
"type": "string",
16-
"enum": ["erc20", "erc721"],
16+
"enum": ["erc20", "erc721", "erc1155"],
1717
"x-enum-descriptions": [
1818
"EIP-20: Token Standard",
19-
"EIP-721: Non-Fungible Token Standard"
19+
"EIP-721: Non-Fungible Token Standard",
20+
"EIP-1155: Multi Token Standard"
2021
],
21-
"x-enum-varnames": ["ERC20", "ERC721"]
22+
"x-enum-varnames": ["ERC20", "ERC721", "ERC1155"]
2223
},
2324
"MonitoredToken": {
2425
"description": "Ethereum tokens that are being monitored by the persistence plugin.",

packages/cactus-plugin-persistence-ethereum/src/main/sql/schema.sql

Lines changed: 212 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,87 @@ CREATE POLICY token_metadata_erc721_delete ON ethereum."token_metadata_erc721"
147147
FOR DELETE TO anon, authenticated, service_role
148148
USING (true);
149149

150+
-- Table: ethereum.token_metadata_erc1155
151+
152+
-- DROP TABLE IF EXISTS ethereum.token_metadata_erc1155;
153+
154+
CREATE TABLE IF NOT EXISTS ethereum.token_metadata_erc1155
155+
(
156+
address text COLLATE pg_catalog."default" NOT NULL,
157+
name text COLLATE pg_catalog."default",
158+
symbol text COLLATE pg_catalog."default",
159+
created_at timestamp with time zone NOT NULL DEFAULT now(),
160+
CONSTRAINT token_metadata_erc1155_pkey PRIMARY KEY (address),
161+
CONSTRAINT token_metadata_erc1155_address_key UNIQUE (address)
162+
);
163+
164+
ALTER TABLE IF EXISTS ethereum.token_metadata_erc1155
165+
OWNER to postgres;
166+
167+
ALTER TABLE ethereum.token_metadata_erc1155
168+
ENABLE ROW LEVEL SECURITY;
169+
170+
CREATE POLICY token_metadata_erc1155_select ON ethereum.token_metadata_erc1155
171+
FOR SELECT TO anon, authenticated, service_role
172+
USING (true);
173+
174+
CREATE POLICY token_metadata_erc1155_insert ON ethereum.token_metadata_erc1155
175+
FOR INSERT TO anon, authenticated, service_role
176+
WITH CHECK (true);
177+
178+
CREATE POLICY token_metadata_erc1155_update ON ethereum.token_metadata_erc1155
179+
FOR UPDATE TO anon, authenticated, service_role
180+
USING (true)
181+
WITH CHECK (true);
182+
183+
CREATE POLICY token_metadata_erc1155_delete ON ethereum.token_metadata_erc1155
184+
FOR DELETE TO anon, authenticated, service_role
185+
USING (true);
186+
187+
-- Table: ethereum.token_erc1155
188+
189+
-- DROP TABLE IF EXISTS ethereum.token_erc1155;
190+
191+
CREATE TABLE IF NOT EXISTS ethereum.token_erc1155
192+
(
193+
id uuid DEFAULT uuid_generate_v4() NOT NULL,
194+
account_address text COLLATE pg_catalog."default" NOT NULL,
195+
token_address text COLLATE pg_catalog."default" NOT NULL,
196+
token_id numeric NOT NULL,
197+
balance numeric NOT NULL DEFAULT 0,
198+
uri text COLLATE pg_catalog."default",
199+
last_balance_change timestamp without time zone NOT NULL DEFAULT now(),
200+
CONSTRAINT token_erc1155_pkey PRIMARY KEY (id),
201+
CONSTRAINT token_erc1155_contract_token_account_unique UNIQUE (token_address, token_id, account_address),
202+
CONSTRAINT token_erc1155_token_address_fkey FOREIGN KEY (token_address)
203+
REFERENCES ethereum.token_metadata_erc1155 (address) MATCH SIMPLE
204+
ON UPDATE NO ACTION
205+
ON DELETE NO ACTION
206+
);
207+
208+
ALTER TABLE IF EXISTS ethereum.token_erc1155
209+
OWNER to postgres;
210+
211+
ALTER TABLE ethereum.token_erc1155
212+
ENABLE ROW LEVEL SECURITY;
213+
214+
CREATE POLICY token_erc1155_select ON ethereum.token_erc1155
215+
FOR SELECT TO anon, authenticated, service_role
216+
USING (true);
217+
218+
CREATE POLICY token_erc1155_insert ON ethereum.token_erc1155
219+
FOR INSERT TO anon, authenticated, service_role
220+
WITH CHECK (true);
221+
222+
CREATE POLICY token_erc1155_update ON ethereum.token_erc1155
223+
FOR UPDATE TO anon, authenticated, service_role
224+
USING (true)
225+
WITH CHECK (true);
226+
227+
CREATE POLICY token_erc1155_delete ON ethereum.token_erc1155
228+
FOR DELETE TO anon, authenticated, service_role
229+
USING (true);
230+
150231
-- Table: ethereum.token_erc721
151232

152233
-- DROP TABLE IF EXISTS ethereum.token_erc721;
@@ -280,8 +361,15 @@ CREATE POLICY token_transfer_delete ON ethereum.token_transfer
280361
FOR DELETE TO anon, authenticated, service_role
281362
USING (true);
282363

364+
-- Adding token_id column to token_transfer for ERC-1155 support
365+
ALTER TABLE ethereum.token_transfer
366+
ADD COLUMN IF NOT EXISTS token_id numeric;
367+
283368
COMMENT ON COLUMN ethereum.token_transfer.value
284-
IS 'ERC20 - token quantity, ERC721 - token ID';
369+
IS 'ERC20 - token quantity, ERC721 - not used (see token_id), ERC1155 - token quantity';
370+
371+
COMMENT ON COLUMN ethereum.token_transfer.token_id
372+
IS 'ERC721 - token ID, ERC1155 - token ID, ERC20 - not used';
285373

286374
----------------------------------------------------------------------------------------------------
287375
-- VIEWS
@@ -332,6 +420,31 @@ WITH (security_invoker = on)
332420
ALTER TABLE ethereum.erc721_token_history_view
333421
OWNER TO postgres;
334422

423+
-- View: ethereum.erc1155_token_history_view
424+
425+
-- DROP VIEW IF EXISTS ethereum.erc1155_token_history_view;
426+
427+
CREATE OR REPLACE VIEW ethereum.erc1155_token_history_view
428+
WITH (security_invoker = on)
429+
AS
430+
SELECT
431+
tx.hash AS transaction_hash,
432+
tx."to" AS token_address,
433+
b.created_at,
434+
tt.sender,
435+
tt.recipient,
436+
tt.token_id,
437+
tt.value AS quantity
438+
FROM ethereum.transaction tx
439+
JOIN ethereum.block b ON tx.block_number = b.number
440+
JOIN ethereum.token_transfer tt ON tx.id = tt.transaction_id
441+
JOIN ethereum.token_metadata_erc1155 tkn ON tx."to" = tkn.address
442+
WHERE tt.token_id IS NOT NULL -- Ensure token_id is present (ERC-1155 or ERC-721)
443+
ORDER BY b.created_at, tt.recipient;
444+
445+
ALTER TABLE ethereum.erc1155_token_history_view
446+
OWNER TO postgres;
447+
335448
-- View: ethereum.token_erc20
336449

337450
-- DROP MATERIALIZED VIEW IF EXISTS ethereum.token_erc20;
@@ -466,6 +579,104 @@ ALTER PROCEDURE ethereum.update_issued_erc721_tokens(numeric)
466579

467580
GRANT EXECUTE ON PROCEDURE ethereum.update_issued_erc721_tokens(numeric) TO public;
468581

582+
-- PROCEDURE: ethereum.update_issued_erc1155_tokens(numeric)
583+
584+
-- DROP PROCEDURE IF EXISTS ethereum.update_issued_erc1155_tokens(numeric);
585+
586+
CREATE OR REPLACE PROCEDURE ethereum.update_issued_erc1155_tokens(IN from_block_number numeric)
587+
LANGUAGE 'plpgsql'
588+
SET search_path = ethereum, public
589+
AS $BODY$
590+
DECLARE
591+
current_token_entry ethereum.token_erc1155%ROWTYPE;
592+
token_transfer record;
593+
block_created_at timestamp;
594+
BEGIN
595+
-- Get the block's creation time
596+
SELECT created_at
597+
FROM ethereum.block
598+
WHERE number = from_block_number
599+
INTO block_created_at;
600+
601+
IF NOT found THEN
602+
raise exception 'invalid block provided: %', from_block_number
603+
USING hint = 'ensure that given block was synchronized correctly';
604+
END IF;
605+
606+
-- Process each transfer (distinct by token_address, token_id, recipient to handle batch transfers)
607+
FOR token_transfer IN SELECT
608+
*
609+
FROM ethereum.erc1155_token_history_view
610+
WHERE created_at >= block_created_at
611+
ORDER BY token_address, token_id, sender, recipient, created_at DESC
612+
LOOP
613+
-- Process sender (decrease balance)
614+
IF token_transfer.sender != '0x0000000000000000000000000000000000000000' THEN -- Not a mint
615+
SELECT * FROM ethereum.token_erc1155
616+
WHERE token_id = token_transfer.token_id
617+
AND token_address = token_transfer.token_address
618+
AND account_address = token_transfer.sender
619+
INTO current_token_entry;
620+
621+
IF found THEN
622+
-- Decrease sender's balance
623+
UPDATE ethereum.token_erc1155
624+
SET balance = GREATEST(0, balance - token_transfer.quantity),
625+
last_balance_change = token_transfer.created_at
626+
WHERE id = current_token_entry.id;
627+
628+
-- Remove entry if balance reaches 0
629+
DELETE FROM ethereum.token_erc1155
630+
WHERE id = current_token_entry.id AND balance = 0;
631+
END IF;
632+
END IF;
633+
634+
-- Process recipient (increase balance)
635+
IF token_transfer.recipient != '0x0000000000000000000000000000000000000000' THEN -- Not a burn
636+
SELECT * FROM ethereum.token_erc1155
637+
WHERE token_id = token_transfer.token_id
638+
AND token_address = token_transfer.token_address
639+
AND account_address = token_transfer.recipient
640+
INTO current_token_entry;
641+
642+
IF NOT found THEN
643+
-- Create new entry for recipient
644+
raise notice 'create entry for token ID % on contract % for account %',
645+
token_transfer.token_id, token_transfer.token_address, token_transfer.recipient;
646+
INSERT INTO ethereum.token_erc1155
647+
VALUES (
648+
uuid_generate_v4(),
649+
token_transfer.recipient,
650+
token_transfer.token_address,
651+
token_transfer.token_id,
652+
token_transfer.quantity,
653+
NULL, -- uri (can be fetched later)
654+
token_transfer.created_at
655+
);
656+
ELSE
657+
-- Increase recipient's balance
658+
IF current_token_entry.last_balance_change < token_transfer.created_at THEN
659+
raise notice 'update balance for token ID % on contract % for account %',
660+
token_transfer.token_id, token_transfer.token_address, token_transfer.recipient;
661+
UPDATE ethereum.token_erc1155
662+
SET balance = balance + token_transfer.quantity,
663+
last_balance_change = token_transfer.created_at
664+
WHERE id = current_token_entry.id;
665+
ELSE
666+
raise notice 'current entry is more recent - ignore token ID % on contract % for account %',
667+
token_transfer.token_id, token_transfer.token_address, token_transfer.recipient;
668+
END IF;
669+
END IF;
670+
END IF;
671+
END LOOP;
672+
END
673+
$BODY$;
674+
675+
ALTER PROCEDURE ethereum.update_issued_erc1155_tokens(numeric)
676+
OWNER TO postgres;
677+
678+
GRANT EXECUTE ON PROCEDURE ethereum.update_issued_erc1155_tokens(numeric) TO public;
679+
469680
-- FUNCTION: ethereum.get_missing_blocks_in_range(integer, integer)
470681

471682
-- DROP FUNCTION IF EXISTS ethereum.get_missing_blocks_in_range(integer, integer);

packages/cactus-plugin-persistence-ethereum/src/main/typescript/db-client/database.types.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,35 @@ export interface Database {
9090
last_owner_change?: string;
9191
};
9292
};
93+
token_erc1155: {
94+
Row: {
95+
id: string;
96+
account_address: string;
97+
token_address: string;
98+
token_id: number;
99+
balance: number;
100+
uri: string | null;
101+
last_balance_change: string;
102+
};
103+
Insert: {
104+
id?: string;
105+
account_address: string;
106+
token_address: string;
107+
token_id: number;
108+
balance: number;
109+
uri?: string | null;
110+
last_balance_change?: string;
111+
};
112+
Update: {
113+
id?: string;
114+
account_address?: string;
115+
token_address?: string;
116+
token_id?: number;
117+
balance: number;
118+
uri?: string | null;
119+
last_balance_change?: string;
120+
};
121+
};
93122
token_metadata_erc20: {
94123
Row: {
95124
address: string;
@@ -133,6 +162,26 @@ export interface Database {
133162
created_at?: string;
134163
};
135164
};
165+
token_metadata_erc1155: {
166+
Row: {
167+
address: string;
168+
name: string | null;
169+
symbol: string | null;
170+
created_at: string;
171+
};
172+
Insert: {
173+
address: string;
174+
name: string | null;
175+
symbol: string | null;
176+
created_at?: string;
177+
};
178+
Update: {
179+
address?: string;
180+
name?: string | null;
181+
symbol?: string | null;
182+
created_at?: string;
183+
};
184+
};
136185
token_transfer: {
137186
Row: {
138187
transaction_id: string;

0 commit comments

Comments
 (0)