@@ -147,6 +147,87 @@ CREATE POLICY token_metadata_erc721_delete ON ethereum."token_metadata_erc721"
147
147
FOR DELETE TO anon, authenticated, service_role
148
148
USING (true);
149
149
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
+
150
231
-- Table: ethereum.token_erc721
151
232
152
233
-- DROP TABLE IF EXISTS ethereum.token_erc721;
@@ -277,8 +358,15 @@ CREATE POLICY token_transfer_delete ON ethereum.token_transfer
277
358
FOR DELETE TO anon, authenticated, service_role
278
359
USING (true);
279
360
361
+ -- Adding token_id column to token_transfer for ERC-1155 support
362
+ ALTER TABLE ethereum .token_transfer
363
+ ADD COLUMN IF NOT EXISTS token_id numeric ;
364
+
280
365
COMMENT ON COLUMN ethereum .token_transfer .value
281
- IS ' ERC20 - token quantity, ERC721 - token ID' ;
366
+ IS ' ERC20 - token quantity, ERC721 - not used (see token_id), ERC1155 - token quantity' ;
367
+
368
+ COMMENT ON COLUMN ethereum .token_transfer .token_id
369
+ IS ' ERC721 - token ID, ERC1155 - token ID, ERC20 - not used' ;
282
370
283
371
-- --------------------------------------------------------------------------------------------------
284
372
-- VIEWS
@@ -329,6 +417,31 @@ WITH (security_invoker = on)
329
417
ALTER TABLE ethereum .erc721_token_history_view
330
418
OWNER TO postgres;
331
419
420
+ -- View: ethereum.erc1155_token_history_view
421
+
422
+ -- DROP VIEW IF EXISTS ethereum.erc1155_token_history_view;
423
+
424
+ CREATE OR REPLACE VIEW ethereum .erc1155_token_history_view
425
+ WITH (security_invoker = on )
426
+ AS
427
+ SELECT
428
+ tx .hash AS transaction_hash,
429
+ tx." to" AS token_address,
430
+ b .created_at ,
431
+ tt .sender ,
432
+ tt .recipient ,
433
+ tt .token_id ,
434
+ tt .value AS quantity
435
+ FROM ethereum .transaction tx
436
+ JOIN ethereum .block b ON tx .block_number = b .number
437
+ JOIN ethereum .token_transfer tt ON tx .id = tt .transaction_id
438
+ JOIN ethereum .token_metadata_erc1155 tkn ON tx." to" = tkn .address
439
+ WHERE tt .token_id IS NOT NULL -- Ensure token_id is present (ERC-1155 or ERC-721)
440
+ ORDER BY b .created_at , tt .recipient ;
441
+
442
+ ALTER TABLE ethereum .erc1155_token_history_view
443
+ OWNER TO postgres;
444
+
332
445
-- View: ethereum.token_erc20
333
446
334
447
-- DROP MATERIALIZED VIEW IF EXISTS ethereum.token_erc20;
@@ -460,6 +573,104 @@ ALTER PROCEDURE ethereum.update_issued_erc721_tokens(numeric)
460
573
461
574
GRANT EXECUTE ON PROCEDURE ethereum .update_issued_erc721_tokens (numeric ) TO public;
462
575
576
+ -- PROCEDURE: ethereum.update_issued_erc1155_tokens(numeric)
577
+
578
+ -- DROP PROCEDURE IF EXISTS ethereum.update_issued_erc1155_tokens(numeric);
579
+
580
+ CREATE OR REPLACE PROCEDURE ethereum .update_issued_erc1155_tokens (IN from_block_number numeric )
581
+ LANGUAGE ' plpgsql'
582
+ SET search_path = ethereum, public
583
+ AS $BODY$
584
+ DECLARE
585
+ current_token_entry ethereum .token_erc1155 %ROWTYPE;
586
+ token_transfer record;
587
+ block_created_at timestamp ;
588
+ BEGIN
589
+ -- Get the block's creation time
590
+ SELECT created_at
591
+ FROM ethereum .block
592
+ WHERE number = from_block_number
593
+ INTO block_created_at;
594
+
595
+ IF NOT found THEN
596
+ raise exception ' invalid block provided: %' , from_block_number
597
+ USING hint = ' ensure that given block was synchronized correctly' ;
598
+ END IF;
599
+
600
+ -- Process each transfer (distinct by token_address, token_id, recipient to handle batch transfers)
601
+ FOR token_transfer IN SELECT
602
+ *
603
+ FROM ethereum .erc1155_token_history_view
604
+ WHERE created_at >= block_created_at
605
+ ORDER BY token_address, token_id, sender, recipient, created_at DESC
606
+ LOOP
607
+ -- Process sender (decrease balance)
608
+ IF token_transfer .sender != ' 0x0000000000000000000000000000000000000000' THEN -- Not a mint
609
+ SELECT * FROM ethereum .token_erc1155
610
+ WHERE token_id = token_transfer .token_id
611
+ AND token_address = token_transfer .token_address
612
+ AND account_address = token_transfer .sender
613
+ INTO current_token_entry;
614
+
615
+ IF found THEN
616
+ -- Decrease sender's balance
617
+ UPDATE ethereum .token_erc1155
618
+ SET balance = GREATEST(0 , balance - token_transfer .quantity ),
619
+ last_balance_change = token_transfer .created_at
620
+ WHERE id = current_token_entry .id ;
621
+
622
+ -- Remove entry if balance reaches 0
623
+ DELETE FROM ethereum .token_erc1155
624
+ WHERE id = current_token_entry .id AND balance = 0 ;
625
+ END IF;
626
+ END IF;
627
+
628
+ -- Process recipient (increase balance)
629
+ IF token_transfer .recipient != ' 0x0000000000000000000000000000000000000000' THEN -- Not a burn
630
+ SELECT * FROM ethereum .token_erc1155
631
+ WHERE token_id = token_transfer .token_id
632
+ AND token_address = token_transfer .token_address
633
+ AND account_address = token_transfer .recipient
634
+ INTO current_token_entry;
635
+
636
+ IF NOT found THEN
637
+ -- Create new entry for recipient
638
+ raise notice ' create entry for token ID % on contract % for account %' ,
639
+ token_transfer .token_id , token_transfer .token_address , token_transfer .recipient ;
640
+ INSERT INTO ethereum .token_erc1155
641
+ VALUES (
642
+ uuid_generate_v4(),
643
+ token_transfer .recipient ,
644
+ token_transfer .token_address ,
645
+ token_transfer .token_id ,
646
+ token_transfer .quantity ,
647
+ NULL , -- uri (can be fetched later)
648
+ token_transfer .created_at
649
+ );
650
+ ELSE
651
+ -- Increase recipient's balance
652
+ IF current_token_entry .last_balance_change < token_transfer .created_at THEN
653
+ raise notice ' update balance for token ID % on contract % for account %' ,
654
+ token_transfer .token_id , token_transfer .token_address , token_transfer .recipient ;
655
+ UPDATE ethereum .token_erc1155
656
+ SET balance = balance + token_transfer .quantity ,
657
+ last_balance_change = token_transfer .created_at
658
+ WHERE id = current_token_entry .id ;
659
+ ELSE
660
+ raise notice ' current entry is more recent - ignore token ID % on contract % for account %' ,
661
+ token_transfer .token_id , token_transfer .token_address , token_transfer .recipient ;
662
+ END IF;
663
+ END IF;
664
+ END IF;
665
+ END LOOP;
666
+ END
667
+ $BODY$;
668
+
669
+ ALTER PROCEDURE ethereum .update_issued_erc1155_tokens (numeric )
670
+ OWNER TO postgres;
671
+
672
+ GRANT EXECUTE ON PROCEDURE ethereum .update_issued_erc1155_tokens (numeric ) TO public;
673
+
463
674
-- FUNCTION: ethereum.get_missing_blocks_in_range(integer, integer)
464
675
465
676
-- DROP FUNCTION IF EXISTS ethereum.get_missing_blocks_in_range(integer, integer);
0 commit comments