An 1605/nft mints refactor (#102)

* refactor nft mints model

* An 1949/bt (#95)

* date limit some program

* block timestamp

* fixes

* fix

* An 1937/blocks txs2 (#94)

* blocks

* transactions and deduping wip

* silver reorganization

* remove tx count from blocks

* wip

* load blocks backfill incrementally

* wip

* wip

* wip

* remove unused comments

* fix ref to wrong table

* update to tests

* test fixes

* moved yawww bids

* merge main & fix refs

Co-authored-by: Desmond Hui <desmond@flipsidecrypto.com>

* description updates (#96)

* fix missing incremental block (#97)

* reduce batch load size (#98)

* Adjust tx2 incremental load size (#99)

* reduce batch load size

* revert change

* revert change

* minor cleanup and add model output comparison test

* move models to nft folder

* add test case

* update/add descriptions and tests

* adjust unique key

* adjust unique key, add columns to output

* add alias for new tx_id name from underlying model

* add index + inner_index to output and unique key

* remove inner index test

* fix unique key

Co-authored-by: Jessica Huhnke <91915469+jhuhnke@users.noreply.github.com>
This commit is contained in:
desmond-hui 2022-09-14 07:50:59 -07:00 committed by GitHub
parent b57c7144e3
commit af2ce900af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 992 additions and 437 deletions

View File

@ -0,0 +1,22 @@
mint,purchaser,mint_currency,mint_price
zsFUFcetxjLCeUaNjsQE57b3c3awU79sVeTZQrsoSq6,748yt6s4kkhFWWLmG5kzBXhsr6hsuCnuTW4hKZ7H8B6C,So11111111111111111111111111111111111111111,1.25847032
8XQqL7wwKrGftLaSnd8Km9WnA6bwT1B1w2NXrxQfxU6t,AnW2XvmP5QmS4Vm2DxcjJ3YzRW7utZg83TAwdPvbQ57e,So11111111111111111111111111111111111111111,0.0119712
8miSwDxQNV9W7LHPRzXEMXwk4oYHU29fxFi5LAaS3Zoo,9FGsCoLTUKYo8GbfpEN4G91UemB7nmy83JXXQN6tV8QH,So11111111111111111111111111111111111111111,0.00847032
CArsPMgQyevzmE4SYDjVaeWvoNwEMsE4cwbCyXrPGtE5,G4A3sTtsk2megbv8q7XpFKio3JgB1jbPXq6KJzQoyF5y,So11111111111111111111111111111111111111111,0.01727472
YcDLuwoqB8yWcfnwNDrjoSo4iuVmTCz27ZXsh6w12mo,8VDvnZ31y9RqiZj8m3i4oPaShmY7CqgHu6tNoyEphSSE,So11111111111111111111111111111111111111111,0.00847032
6HBSxEKHJzS19aKhFhzWeYRM9QezKk1QGKug3QLFw8AU,3BNjZikUrvdvsHeTjCUrr8bLEtPVBP2oZnSAxtbcQh9a,So11111111111111111111111111111111111111111,0.0105096
3ry2VrRvehb6Z7roeXaAzzQuqheeM2wyWHTmgMUtZZSk,3BNjZikUrvdvsHeTjCUrr8bLEtPVBP2oZnSAxtbcQh9a,So11111111111111111111111111111111111111111,0.0105096
FUHUjD4z1YDDRGqZAL4n89HsuDEFhVLcoz47LJirCnBm,5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p,So11111111111111111111111111111111111111111,0.0091176
FaC8SaDj6crwZA5JyucbKuTDbbTLbCSVpGbLVSXxaxJ4,5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p,So11111111111111111111111111111111111111111,0.0091176
BxGPRSEzHwEzX73Ep67a9u5xFc2BSuXSrAevqNMkzN8Z,5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p,So11111111111111111111111111111111111111111,0.0091176
HrbK1X3ooR2fBujtDSWeKQtbj1fUtptrEb7mWvsxeQQk,5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p,So11111111111111111111111111111111111111111,0.0091176
CmejwsHB1hcQPbY7y4EjYD5gxWJEXn9G4PkXLpLoTus1,5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p,So11111111111111111111111111111111111111111,0.0091176
JBzLjej5DEtVupwVtn6y1mnG4HFEkm5PVxQYFNYMJzhc,GPzYDMBnzCNJm7bx9EUVAN6NDYZPYC73YGm9Jypi7LFY,So11111111111111111111111111111111111111111,0.00847032
JBzLjej5DEtVupwVtn6y1mnG4HFEkm5PVxQYFNYMJzhc,GPzYDMBnzCNJm7bx9EUVAN6NDYZPYC73YGm9Jypi7LFY,GzpRsvnKXKz586kRLkjdppR4dUCFwHa2qaszKkPUQx6g,80000
J5EFUxYPxAyx5oCUUgmCrESHjhmXuzrYsscoxRvVW5Vz,ELdfaUoVQ6uP49t1ZuuMajoadjMVLNVDfQQiuxChS4p5,So11111111111111111111111111111111111111111,0.00937512
DCahWcCagbsW8HAqu4QMDaQZn212MrA7aN4yLNKYn3tY,7eAf79f5qpBCPMsZggwoieBGUHiGwhTxCtviXzsNJ33k,So11111111111111111111111111111111111111111,2.00847032
58MAJPUgfSyehsKggYEeWjpNZaKw5qxnLNZ4EKeRicmq,8B3NLjV9waB1HAtN5ksz4ymYhjjAwjT9NXFXvCen2UVy,So11111111111111111111111111111111111111111,0.00847032
Dq6H4jMXQkHEf3q3BocptwF7Nh6V9FZwABXuVRgRXtts,93oV7JEMxrzqZzcdqWtwoy2cfpmobBpWqcQwXLdnCRgh,So11111111111111111111111111111111111111111,0.00847032
Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN,3hNzvJcbjdhwt14cWkJMYUYFvNbVxLoS8cmrkqfAFVeM,So11111111111111111111111111111111111111111,0.00561672
Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN,3hNzvJcbjdhwt14cWkJMYUYFvNbVxLoS8cmrkqfAFVeM,GENEtH5amGSi8kHAtQoezp1XEXwZJ8vcuePYnXdKrMYz,10
Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN,GenoS3ck8xbDvYEZ8RxMG3Ln2qcyoAN8CTeZuaWgAoEA,So11111111111111111111111111111111111111111,0.0028536
1 mint purchaser mint_currency mint_price
2 zsFUFcetxjLCeUaNjsQE57b3c3awU79sVeTZQrsoSq6 748yt6s4kkhFWWLmG5kzBXhsr6hsuCnuTW4hKZ7H8B6C So11111111111111111111111111111111111111111 1.25847032
3 8XQqL7wwKrGftLaSnd8Km9WnA6bwT1B1w2NXrxQfxU6t AnW2XvmP5QmS4Vm2DxcjJ3YzRW7utZg83TAwdPvbQ57e So11111111111111111111111111111111111111111 0.0119712
4 8miSwDxQNV9W7LHPRzXEMXwk4oYHU29fxFi5LAaS3Zoo 9FGsCoLTUKYo8GbfpEN4G91UemB7nmy83JXXQN6tV8QH So11111111111111111111111111111111111111111 0.00847032
5 CArsPMgQyevzmE4SYDjVaeWvoNwEMsE4cwbCyXrPGtE5 G4A3sTtsk2megbv8q7XpFKio3JgB1jbPXq6KJzQoyF5y So11111111111111111111111111111111111111111 0.01727472
6 YcDLuwoqB8yWcfnwNDrjoSo4iuVmTCz27ZXsh6w12mo 8VDvnZ31y9RqiZj8m3i4oPaShmY7CqgHu6tNoyEphSSE So11111111111111111111111111111111111111111 0.00847032
7 6HBSxEKHJzS19aKhFhzWeYRM9QezKk1QGKug3QLFw8AU 3BNjZikUrvdvsHeTjCUrr8bLEtPVBP2oZnSAxtbcQh9a So11111111111111111111111111111111111111111 0.0105096
8 3ry2VrRvehb6Z7roeXaAzzQuqheeM2wyWHTmgMUtZZSk 3BNjZikUrvdvsHeTjCUrr8bLEtPVBP2oZnSAxtbcQh9a So11111111111111111111111111111111111111111 0.0105096
9 FUHUjD4z1YDDRGqZAL4n89HsuDEFhVLcoz47LJirCnBm 5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p So11111111111111111111111111111111111111111 0.0091176
10 FaC8SaDj6crwZA5JyucbKuTDbbTLbCSVpGbLVSXxaxJ4 5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p So11111111111111111111111111111111111111111 0.0091176
11 BxGPRSEzHwEzX73Ep67a9u5xFc2BSuXSrAevqNMkzN8Z 5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p So11111111111111111111111111111111111111111 0.0091176
12 HrbK1X3ooR2fBujtDSWeKQtbj1fUtptrEb7mWvsxeQQk 5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p So11111111111111111111111111111111111111111 0.0091176
13 CmejwsHB1hcQPbY7y4EjYD5gxWJEXn9G4PkXLpLoTus1 5PJh6ywVqXTUcwrJyF6nbkgqmmoXEJSXa7rhh3MWQZ7p So11111111111111111111111111111111111111111 0.0091176
14 JBzLjej5DEtVupwVtn6y1mnG4HFEkm5PVxQYFNYMJzhc GPzYDMBnzCNJm7bx9EUVAN6NDYZPYC73YGm9Jypi7LFY So11111111111111111111111111111111111111111 0.00847032
15 JBzLjej5DEtVupwVtn6y1mnG4HFEkm5PVxQYFNYMJzhc GPzYDMBnzCNJm7bx9EUVAN6NDYZPYC73YGm9Jypi7LFY GzpRsvnKXKz586kRLkjdppR4dUCFwHa2qaszKkPUQx6g 80000
16 J5EFUxYPxAyx5oCUUgmCrESHjhmXuzrYsscoxRvVW5Vz ELdfaUoVQ6uP49t1ZuuMajoadjMVLNVDfQQiuxChS4p5 So11111111111111111111111111111111111111111 0.00937512
17 DCahWcCagbsW8HAqu4QMDaQZn212MrA7aN4yLNKYn3tY 7eAf79f5qpBCPMsZggwoieBGUHiGwhTxCtviXzsNJ33k So11111111111111111111111111111111111111111 2.00847032
18 58MAJPUgfSyehsKggYEeWjpNZaKw5qxnLNZ4EKeRicmq 8B3NLjV9waB1HAtN5ksz4ymYhjjAwjT9NXFXvCen2UVy So11111111111111111111111111111111111111111 0.00847032
19 Dq6H4jMXQkHEf3q3BocptwF7Nh6V9FZwABXuVRgRXtts 93oV7JEMxrzqZzcdqWtwoy2cfpmobBpWqcQwXLdnCRgh So11111111111111111111111111111111111111111 0.00847032
20 Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN 3hNzvJcbjdhwt14cWkJMYUYFvNbVxLoS8cmrkqfAFVeM So11111111111111111111111111111111111111111 0.00561672
21 Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN 3hNzvJcbjdhwt14cWkJMYUYFvNbVxLoS8cmrkqfAFVeM GENEtH5amGSi8kHAtQoezp1XEXwZJ8vcuePYnXdKrMYz 10
22 Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN GenoS3ck8xbDvYEZ8RxMG3Ln2qcyoAN8CTeZuaWgAoEA So11111111111111111111111111111111111111111 0.0028536

View File

@ -0,0 +1,29 @@
{% test compare_model_subset(model, compare_model, compare_columns, model_condition) %}
{% set compare_cols_csv = compare_columns | join(', ') %}
with a as (
select {{compare_cols_csv}} from {{ model }}
{{ model_condition }}
),
b as (
select {{compare_cols_csv}} from {{ compare_model }}
),
a_minus_b as (
select * from a
{{ dbt_utils.except() }}
select * from b
),
b_minus_a as (
select * from b
{{ dbt_utils.except() }}
select * from a
),
unioned as (
select 'in_actual_not_in_expected' as which_diff, a_minus_b.* from a_minus_b
union all
select 'in_expected_not_in_actual' as which_diff, b_minus_a.* from b_minus_a
)
select * from unioned
{% endtest %}

View File

@ -5,7 +5,7 @@
SELECT
block_timestamp,
block_id,
tx_id,
initialization_tx_id as tx_id,
succeeded,
program_id,
purchaser,

View File

@ -0,0 +1,5 @@
{% docs decimal %}
Number of decimals in the token value, need to divide amount by 10^decimal
{% enddocs %}

View File

@ -1,5 +1,5 @@
{% docs event_index %}
Location of the event within the instructions of a transaction
Location of the instruction (event) within a transaction
{% enddocs %}

View File

@ -0,0 +1,5 @@
{% docs mint_amount %}
Number of tokens minted
{% enddocs %}

View File

@ -0,0 +1,5 @@
{% docs mint_payer %}
Wallet address associated with paying for the mint
{% enddocs %}

View File

@ -0,0 +1,52 @@
{{ config(
materialized = 'view'
) }}
with base as (
select
block_timestamp,
tx_ids,
program_id,
payer,
mint,
mint_currency,
mint_price,
_inserted_timestamp,
1 as ranking
from
{{ ref('silver__nft_mint_price_candy_machine') }}
union
select
block_timestamp,
tx_ids,
program_id,
payer,
mint,
mint_currency,
mint_price,
_inserted_timestamp,
2 as ranking
from
{{ ref('silver__nft_mint_price_other') }}
where
mint_price is not null
union
select
block_timestamp,
tx_ids,
program_id,
payer,
mint,
mint_currency,
mint_price,
_inserted_timestamp,
99 as ranking
from
{{ ref('silver__nft_mint_price_generic') }}
where
mint_price is not null
)
select
*
from base
qualify(row_number() over (partition by mint, payer, mint_currency order by ranking)) = 1

View File

@ -0,0 +1,50 @@
version: 2
models:
- name: silver__nft_mint_price
description: intermediary model for getting an nft's mint price
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- MINT
- PAYER
- MINT_CURRENCY
columns:
- name: BLOCK_TIMESTAMP
description: "block timestamp of the latest transaction with a mint price"
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: day
interval: 3
- name: TX_IDS
description: "set of transaction ids that has an associated mint price"
tests:
- not_null
- name: MINT
description: "{{ doc('mint') }}"
tests:
- not_null
- name: PAYER
description: "{{ doc('mint_payer') }}"
tests:
- not_null:
where: mint_price is not null
- name: MINT_CURRENCY
description: "{{ doc('mint_currency') }}"
tests:
- not_null:
where: mint_price is not null
- name: PROGRAM_ID
description: "{{ doc('program_id') }}"
tests:
- not_null
- name: MINT_PRICE
description: "{{ doc('mint_price') }}"
- name: RANKING
description: ranking order for which model to take mint price from first
tests:
- not_null
- name: _INSERTED_TIMESTAMP
description: "{{ doc('_inserted_timestamp') }}"
tests:
- not_null

View File

@ -0,0 +1,100 @@
{{ config(
materialized = 'incremental',
unique_key = "CONCAT_WS('-', mint, payer, mint_currency)",
incremental_strategy = 'delete+insert',
cluster_by = ['block_timestamp::DATE','_inserted_timestamp::DATE'],
) }}
WITH base_candy_machine_events AS (
SELECT
*
FROM
{{ ref('silver__events') }}
WHERE
program_id = 'cndy3Z4yapfJBmL3ShUp5exZKqR3z33thTzeNMm2gRZ'
AND
succeeded
{% if is_incremental() %}
AND
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
base_ptb AS (
SELECT
DISTINCT mint AS mint_paid,
account,
DECIMAL
FROM
{{ ref('silver___post_token_balances') }}
{% if is_incremental() %}
WHERE
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
candy_machine AS (
SELECT
e.block_timestamp,
e.tx_id,
e.index,
i.index as inner_index,
e.program_id,
instruction :accounts [5] :: STRING AS mint,
instruction :accounts [2] :: STRING AS payer,
COALESCE(
i.value :parsed :info :lamports :: INTEGER,
i.value :parsed :info :amount :: INTEGER
) AS transfer_amount,
CASE
WHEN i.value :parsed :info :lamports is not null THEN NULL
ELSE i.value :parsed :info :source
END as token_account,
e._inserted_timestamp
FROM
base_candy_machine_events e
LEFT JOIN TABLE(FLATTEN(inner_instruction :instructions)) i
group by 1,2,3,4,5,6,7,8,9,10
),
pre_final as (
select
e.*,
COALESCE(
p.mint_paid,
'So11111111111111111111111111111111111111111'
) AS mint_currency,
COALESCE(p.decimal, 9) as decimal
from candy_machine e
LEFT OUTER JOIN base_ptb p on e.token_account = p.account
)
SELECT
p.mint,
p.payer,
mint_currency,
decimal,
p.program_id,
SUM(p.transfer_amount / pow(10, decimal)) AS mint_price,
array_unique_agg(tx_id) as tx_ids,
max(block_timestamp) as block_timestamp,
max(_inserted_timestamp) as _inserted_timestamp
FROM
pre_final p
WHERE
p.mint not in ('Sysvar1nstructions1111111111111111111111111','SysvarRent111111111111111111111111111111111') -- not mint events
GROUP BY
1,
2,
3,
4,
5

View File

@ -0,0 +1,51 @@
version: 2
models:
- name: silver__nft_mint_price_candy_machine
description: intermediary model for getting an nft's mint price
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- MINT
- PAYER
- MINT_CURRENCY
where: mint <> 'GqzH4GRCqqsNXAvx9FSK7n3pMqRCjnyns7pqe94yAV1M'
columns:
- name: BLOCK_TIMESTAMP
description: "block timestamp of the latest transaction with a mint price"
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: day
interval: 3
- name: TX_IDS
description: "set of transaction ids that has an associated mint price"
tests:
- not_null
- name: MINT
description: "{{ doc('mint') }}"
tests:
- not_null
- name: PAYER
description: "{{ doc('mint_payer') }}"
tests:
- not_null:
where: mint_price is not null
- name: MINT_CURRENCY
description: "{{ doc('mint_currency') }}"
tests:
- not_null:
where: mint_price is not null
- name: DECIMAL
description: "{{ doc('decimal') }}"
tests:
- not_null
- name: PROGRAM_ID
description: "{{ doc('program_id') }}"
tests:
- not_null
- name: MINT_PRICE
description: "{{ doc('mint_price') }}"
- name: _INSERTED_TIMESTAMP
description: "{{ doc('_inserted_timestamp') }}"
tests:
- not_null

View File

@ -0,0 +1,171 @@
{{ config(
materialized = 'incremental',
unique_key = "CONCAT_WS('-', mint, payer, mint_currency)",
incremental_strategy = 'delete+insert',
cluster_by = ['block_timestamp::DATE','_inserted_timestamp::DATE'],
) }}
WITH base_events AS (
SELECT
*
FROM
{{ ref('silver__events') }}
WHERE succeeded
{% if is_incremental() %}
AND
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
base_ptb AS (
SELECT
distinct mint AS mint_paid,
account,
DECIMAL
FROM
{{ ref('silver___post_token_balances') }}
{% if is_incremental() %}
WHERE
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
metaplex_events AS (
SELECT
block_id,
block_timestamp,
tx_id,
e.succeeded,
e.program_id,
e.index,
e.instruction :accounts AS accounts,
ARRAY_SIZE(accounts) AS num_accounts,
e.inner_instruction,
_inserted_timestamp
FROM
base_events e,
TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
program_id = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
AND succeeded
AND (
(ARRAY_SIZE(accounts) = 7
AND accounts [5] = '11111111111111111111111111111111'
AND accounts [6] = 'SysvarRent111111111111111111111111111111111')
OR (ARRAY_SIZE(accounts) = 9
AND accounts [7] = '11111111111111111111111111111111'
AND accounts [8] = 'SysvarRent111111111111111111111111111111111')
OR (ARRAY_SIZE(accounts) = 14
AND accounts [11] = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
AND accounts [12] = '11111111111111111111111111111111'
AND accounts [13] = 'SysvarRent111111111111111111111111111111111')
OR (ARRAY_SIZE(accounts) = 17
AND accounts [13] = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
AND accounts [14] = 'vau1zxA2LbssAUEF7Gpw91zMM1LvXrvpzJtmZ58rPsn'
AND accounts [15] = '11111111111111111111111111111111'
AND accounts [16] = 'SysvarRent111111111111111111111111111111111'))
UNION
SELECT
block_id,
block_timestamp,
tx_id,
e.succeeded,
e.program_id,
e.index,
i.value :accounts AS accounts,
ARRAY_SIZE(accounts) AS num_accounts,
e.inner_instruction,
_inserted_timestamp
FROM
base_events e,
TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
i.value :programId :: STRING = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
AND succeeded
AND (
(ARRAY_SIZE(accounts) = 7
AND accounts [5] = '11111111111111111111111111111111'
AND accounts [6] = 'SysvarRent111111111111111111111111111111111')
OR (ARRAY_SIZE(accounts) = 9
AND accounts [7] = '11111111111111111111111111111111'
AND accounts [8] = 'SysvarRent111111111111111111111111111111111')
OR (ARRAY_SIZE(accounts) = 14
AND accounts [11] = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
AND accounts [12] = '11111111111111111111111111111111'
AND accounts [13] = 'SysvarRent111111111111111111111111111111111')
OR (ARRAY_SIZE(accounts) = 17
AND accounts [13] = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
AND accounts [14] = 'vau1zxA2LbssAUEF7Gpw91zMM1LvXrvpzJtmZ58rPsn'
AND accounts [15] = '11111111111111111111111111111111'
AND accounts [16] = 'SysvarRent111111111111111111111111111111111'))
),
mint_price_events AS (
SELECT
me.block_timestamp,
me.tx_id,
me.index,
i.index as inner_index,
'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s' as program_id,
CASE
WHEN num_accounts in (14,17) THEN me.accounts [3] :: STRING
ELSE me.accounts [1] :: STRING
END AS mint,
CASE
WHEN num_accounts in (14,17) THEN me.accounts [6] :: STRING
WHEN num_accounts = 9 THEN me.accounts [4] :: STRING
ELSE me.accounts [3] :: STRING
END AS payer,
COALESCE(
i.value :parsed :info :lamports :: INTEGER,
i.value :parsed :info :amount :: INTEGER
) AS transfer_amount,
CASE
WHEN i.value :parsed :info :lamports is not null THEN NULL
ELSE i.value :parsed :info :source
END as token_account,
me._inserted_timestamp
FROM
metaplex_events me
LEFT JOIN TABLE(FLATTEN(inner_instruction :instructions)) i
group by 1,2,3,4,5,6,7,8,9,10
),
pre_final as (
select
e.*,
COALESCE(
p.mint_paid,
'So11111111111111111111111111111111111111111'
) AS mint_currency,
COALESCE(p.decimal, 9) as decimal
from mint_price_events e
LEFT OUTER JOIN base_ptb p on e.token_account = p.account
)
SELECT
p.mint,
p.payer,
mint_currency,
decimal,
p.program_id,
SUM(p.transfer_amount / pow(10, decimal)) AS mint_price,
array_unique_agg(tx_id) as tx_ids,
max(block_timestamp) as block_timestamp,
max(_inserted_timestamp) as _inserted_timestamp
FROM
pre_final p
GROUP BY
1,
2,
3,
4,
5

View File

@ -1,56 +1,49 @@
version: 2
models:
- name: silver__nft_mints_tmp
- name: silver__nft_mint_price_generic
description: intermediary model for getting an nft's mint price
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- TX_ID
- MINT
- PAYER
- MINT_CURRENCY
columns:
- name: BLOCK_TIMESTAMP
description: "{{ doc('block_timestamp') }}"
description: "block timestamp of the latest transaction with a mint price"
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: day
interval: 3
- name: BLOCK_ID
description: "{{ doc('block_id') }}"
- name: TX_IDS
description: "set of transaction ids that has an associated mint price"
tests:
- not_null
- name: TX_ID
description: "{{ doc('tx_id') }}"
tests:
- not_null
- name: SUCCEEDED
description: "{{ doc('tx_succeeded') }}"
tests:
- dbt_expectations.expect_column_to_exist
- name: PROGRAM_ID
description: "{{ doc('program_id') }}"
- name: MINT
description: "{{ doc('mint') }}"
tests:
- not_null
- name: PURCHASER
description: "{{ doc('purchaser') }}"
- name: PAYER
description: "{{ doc('mint_payer') }}"
tests:
- not_null
- not_null:
where: mint_price is not null
- name: MINT_CURRENCY
description: "{{ doc('mint_currency') }}"
tests:
- not_null:
where: mint_price is not null
- name: DECIMAL
description: "{{ doc('decimal') }}"
tests:
- not_null
- name: MINT
description: "{{ doc('mint') }}"
- name: PROGRAM_ID
description: "{{ doc('program_id') }}"
tests:
- not_null
- name: MINT_PRICE
description: "{{ doc('mint_price') }}"
tests:
- not_null
- name: INGESTED_AT
description: " {{ doc('ingested_at') }} "
tests:
- not_null
- name: _INSERTED_TIMESTAMP
description: "{{ doc('_inserted_timestamp') }}"
tests:

View File

@ -0,0 +1,186 @@
{{ config(
materialized = 'incremental',
unique_key = "CONCAT_WS('-', mint, payer, mint_currency)",
incremental_strategy = 'delete+insert',
cluster_by = ['block_timestamp::DATE','_inserted_timestamp::DATE'],
) }}
WITH base_events AS (
SELECT
*
FROM
{{ ref('silver__events') }}
WHERE succeeded
{% if is_incremental() %}
AND
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
base_ptb AS (
SELECT
DISTINCT mint AS mint_paid,
account,
DECIMAL
FROM
{{ ref('silver___post_token_balances') }}
{% if is_incremental() %}
WHERE
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
--unknown program...
hweq_fallback AS (
SELECT
e.block_timestamp,
e.tx_id,
e.index,
i.index as inner_index,
e.program_id,
instruction :accounts [2] :: STRING AS mint,
instruction :accounts [0] :: STRING AS payer,
COALESCE(
i.value :parsed :info :lamports :: INTEGER,
i.value :parsed :info :amount :: INTEGER
) AS transfer_amount,
CASE
WHEN i.value :parsed :info :lamports is not null THEN NULL
ELSE i.value :parsed :info :source
END as token_account,
e._inserted_timestamp
FROM
base_events e
LEFT JOIN TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
program_id = 'HWeQ1ntizxmbMwVHemf9zncf2h6RTTfLiuzbjD9wAN9e'
AND ARRAY_SIZE(
instruction :accounts
) > 7
group by 1,2,3,4,5,6,7,8,9,10
),
--unknown program...
multi_mints_fallback AS (
SELECT
e.block_timestamp,
e.tx_id,
e.index,
i.index as inner_index,
e.program_id,
instruction :accounts [17] :: STRING AS mint,
instruction :accounts [2] :: STRING AS payer,
COALESCE(
i.value :parsed :info :lamports :: INTEGER,
i.value :parsed :info :amount :: INTEGER
) AS transfer_amount,
CASE
WHEN i.value :parsed :info :lamports is not null THEN NULL
ELSE i.value :parsed :info :source
END as token_account,
e._inserted_timestamp
FROM
base_events e
LEFT JOIN TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
program_id = '5WTCguyGQDrFosVn8M9JynwdoRpQJUPuzaembMwug35r'
AND instruction :data :: STRING LIKE '2z8AjPpeqe%'
AND mint is not null
AND inner_index < 17
group by 1,2,3,4,5,6,7,8,9,10
UNION
SELECT
e.block_timestamp,
e.tx_id,
e.index,
i.index as inner_index,
e.program_id,
instruction :accounts [21] :: STRING AS mint,
instruction :accounts [2] :: STRING AS payer,
COALESCE(
i.value :parsed :info :lamports :: INTEGER,
i.value :parsed :info :amount :: INTEGER
) AS transfer_amount,
CASE
WHEN i.value :parsed :info :lamports is not null THEN NULL
ELSE i.value :parsed :info :source
END as token_account,
e._inserted_timestamp
FROM
base_events e
LEFT JOIN TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
program_id = '5WTCguyGQDrFosVn8M9JynwdoRpQJUPuzaembMwug35r'
AND instruction :data :: STRING LIKE '2z8AjPpeqe%'
AND mint is not null
AND inner_index >= 17
group by 1,2,3,4,5,6,7,8,9,10
),
hweq_pre_final as (
select
e.*,
COALESCE(
p.mint_paid,
'So11111111111111111111111111111111111111111'
) AS mint_currency,
COALESCE(p.decimal, 9) as decimal
from hweq_fallback e
LEFT OUTER JOIN base_ptb p on e.token_account = p.account
),
multi_mints_pre_final as (
select
e.*,
COALESCE(
p.mint_paid,
'So11111111111111111111111111111111111111111'
) AS mint_currency,
COALESCE(p.decimal, 9) as decimal
from multi_mints_fallback e
LEFT OUTER JOIN base_ptb p on e.token_account = p.account
)
SELECT
p.mint,
p.payer,
mint_currency,
decimal,
p.program_id,
SUM(p.transfer_amount / pow(10, decimal)) AS mint_price,
array_unique_agg(tx_id) as tx_ids,
max(block_timestamp) as block_timestamp,
max(_inserted_timestamp) as _inserted_timestamp
FROM
hweq_pre_final p
GROUP BY
1,
2,
3,
4,
5
UNION
SELECT
p.mint,
p.payer,
mint_currency,
decimal,
p.program_id,
SUM(p.transfer_amount / pow(10, decimal)) AS mint_price,
array_unique_agg(tx_id) as tx_ids,
max(block_timestamp) as block_timestamp,
max(_inserted_timestamp) as _inserted_timestamp
FROM
multi_mints_pre_final p
GROUP BY
1,
2,
3,
4,
5

View File

@ -0,0 +1,48 @@
version: 2
models:
- name: silver__nft_mint_price_other
description: intermediary model for getting an nft's mint price
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- MINT
- PAYER
- MINT_CURRENCY
where: mint <> 'GqzH4GRCqqsNXAvx9FSK7n3pMqRCjnyns7pqe94yAV1M' # seems like a special token, actually minted twice?
columns:
- name: BLOCK_TIMESTAMP
description: "block timestamp of the latest transaction with a mint price"
tests:
- not_null
- name: TX_IDS
description: "set of transaction ids that has an associated mint price"
tests:
- not_null
- name: MINT
description: "{{ doc('mint') }}"
tests:
- not_null
- name: PAYER
description: "{{ doc('mint_payer') }}"
tests:
- not_null:
where: mint_price is not null
- name: MINT_CURRENCY
description: "{{ doc('mint_currency') }}"
tests:
- not_null:
where: mint_price is not null
- name: DECIMAL
description: "{{ doc('decimal') }}"
tests:
- not_null
- name: PROGRAM_ID
description: "{{ doc('program_id') }}"
tests:
- not_null
- name: MINT_PRICE
description: "{{ doc('mint_price') }}"
- name: _INSERTED_TIMESTAMP
description: "{{ doc('_inserted_timestamp') }}"
tests:
- not_null

View File

@ -1,115 +1,112 @@
{{ config(
materialized = 'incremental',
unique_key = "CONCAT_WS('-', tx_id, mint, mint_currency)",
unique_key = "CONCAT_WS('-', initialization_tx_id, mint, purchaser, mint_currency)",
incremental_strategy = 'delete+insert',
cluster_by = ['block_timestamp::DATE'],
) }}
WITH b AS (
WITH base_mint_actions AS (
SELECT
tx_id
*
FROM
{{ ref('silver__events') }}
e
{{ ref('silver__mint_actions') }}
{% if is_incremental() %}
WHERE
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
base_mint_price AS (
SELECT
*
FROM
{{ ref('silver__nft_mint_price') }}
{% if is_incremental() %}
WHERE
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
initialization AS (
SELECT
*
FROM
base_mint_actions
WHERE
event_type IN (
'mintTo',
'initializeMint'
'initializeMint',
'initializeMint2'
)
AND succeeded
{% if is_incremental() %}
AND e._inserted_timestamp >= (
),
first_mint AS (
SELECT
MAX(_inserted_timestamp)
*
FROM
{{ this }}
)
{% endif %}
EXCEPT
SELECT
tx_id
FROM
{{ ref('silver__nft_mints_tmp') }}
m
{% if is_incremental() %}
WHERE m._inserted_timestamp >= (
base_mint_actions
WHERE
event_type NOT IN (
'initializeMint',
'initializeMint2'
)
AND succeeded qualify(ROW_NUMBER() over (PARTITION BY mint
ORDER BY
block_timestamp)) = 1
),
pre_final AS (
SELECT
MAX(_inserted_timestamp)
i.block_id,
i.block_timestamp,
i.tx_id,
i.succeeded,
i.mint,
i.decimal,
f.mint_amount,
i._inserted_timestamp
FROM
{{ this }}
)
{% endif %}
initialization i
LEFT OUTER JOIN first_mint f
ON i.mint = f.mint
),
b AS (
SELECT
*,
CASE
WHEN DECIMAL = 0
AND mint_amount = 1 THEN 'nft'
WHEN DECIMAL <> 0
OR mint_amount > 1 THEN 'token'
ELSE 'unknown'
END AS mint_type
FROM
pre_final
)
SELECT
block_timestamp,
block_id,
tx_id,
succeeded,
program_id,
purchaser,
mint_currency,
mint,
mint_price,
ingested_at,
_inserted_timestamp
b.block_id,
b.block_timestamp,
b.succeeded,
b.tx_id as initialization_tx_id,
mp.program_id,
mp.payer as purchaser,
b.mint,
mp.mint_currency,
mp.mint_price,
b._inserted_timestamp
FROM
{{ ref('silver__nft_mints_tmp') }}
e
{% if is_incremental() %}
WHERE e._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
UNION
SELECT
e.block_timestamp,
e.block_id,
e.tx_id,
e.succeeded,
e.program_id,
COALESCE(
instruction :parsed :info :mintAuthority :: STRING,
instruction :parsed :info :multisigMintAuthority :: STRING
) AS purchaser,
NULL AS mint_currency,
instruction :parsed :info :mint :: STRING AS mint,
NULL AS mint_price,
e.ingested_at,
e._inserted_timestamp
FROM
{{ ref('silver__events') }}
e
INNER JOIN b
ON b.tx_id = e.tx_id
b
LEFT OUTER JOIN base_mint_price mp
ON b.mint = mp.mint
WHERE
event_type IN (
'mintTo',
'initializeMint'
b.mint_type IN (
'nft',
'unknown'
)
{% if is_incremental() %}
AND e._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
GROUP BY
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11

View File

@ -4,9 +4,25 @@ models:
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- TX_ID
- INITIALIZATION_TX_ID
- MINT
- PURCHASER
- MINT_CURRENCY
- compare_model_subset:
name: silver__nft_mints_business_logic_test
compare_model: ref('testing__nft_mints')
compare_columns:
- mint
- purchaser
- mint_currency
- round(mint_price,8)
model_condition: "where mint in ('zsFUFcetxjLCeUaNjsQE57b3c3awU79sVeTZQrsoSq6','8XQqL7wwKrGftLaSnd8Km9WnA6bwT1B1w2NXrxQfxU6t',
'8miSwDxQNV9W7LHPRzXEMXwk4oYHU29fxFi5LAaS3Zoo','CArsPMgQyevzmE4SYDjVaeWvoNwEMsE4cwbCyXrPGtE5','YcDLuwoqB8yWcfnwNDrjoSo4iuVmTCz27ZXsh6w12mo',
'6HBSxEKHJzS19aKhFhzWeYRM9QezKk1QGKug3QLFw8AU','3ry2VrRvehb6Z7roeXaAzzQuqheeM2wyWHTmgMUtZZSk','FUHUjD4z1YDDRGqZAL4n89HsuDEFhVLcoz47LJirCnBm',
'FaC8SaDj6crwZA5JyucbKuTDbbTLbCSVpGbLVSXxaxJ4','BxGPRSEzHwEzX73Ep67a9u5xFc2BSuXSrAevqNMkzN8Z','HrbK1X3ooR2fBujtDSWeKQtbj1fUtptrEb7mWvsxeQQk',
'CmejwsHB1hcQPbY7y4EjYD5gxWJEXn9G4PkXLpLoTus1','JBzLjej5DEtVupwVtn6y1mnG4HFEkm5PVxQYFNYMJzhc','J5EFUxYPxAyx5oCUUgmCrESHjhmXuzrYsscoxRvVW5Vz',
'DCahWcCagbsW8HAqu4QMDaQZn212MrA7aN4yLNKYn3tY','58MAJPUgfSyehsKggYEeWjpNZaKw5qxnLNZ4EKeRicmq','Dq6H4jMXQkHEf3q3BocptwF7Nh6V9FZwABXuVRgRXtts',
'Ar9mEJ7qJ1uAgkWduKGo3UYVbPMdKrmWxs5z2wgZgbgN')"
columns:
- name: BLOCK_TIMESTAMP
description: "{{ doc('block_timestamp') }}"
@ -19,7 +35,7 @@ models:
description: "{{ doc('block_id') }}"
tests:
- not_null
- name: TX_ID
- name: INITIALIZATION_TX_ID
description: "{{ doc('tx_id') }}"
tests:
- not_null
@ -30,16 +46,18 @@ models:
- name: PROGRAM_ID
description: "{{ doc('program_id') }}"
tests:
- not_null
- not_null:
where: mint_price is not null
- name: PURCHASER
description: "{{ doc('purchaser') }}"
tests:
- not_null
- not_null:
where: mint_price is not null
- name: MINT_CURRENCY
description: "{{ doc('mint_currency') }}"
tests:
- not_null:
enabled: FALSE
where: mint_price is not null
- name: MINT
description: "{{ doc('mint') }}"
tests:
@ -49,10 +67,6 @@ models:
tests:
- not_null:
enabled: FALSE
- name: INGESTED_AT
description: " {{ doc('ingested_at') }} "
tests:
- not_null
- name: _INSERTED_TIMESTAMP
description: "{{ doc('_inserted_timestamp') }}"
tests:

View File

@ -1,307 +0,0 @@
{{ config(
materialized = 'incremental',
unique_key = "CONCAT_WS('-', tx_id, mint, mint_currency)",
incremental_strategy = 'delete+insert',
cluster_by = ['block_timestamp::DATE'],
) }}
WITH mint_tx_tmp AS (
SELECT
t.tx_id,
t.signers [0] :: STRING AS signer,
CASE
WHEN ARRAY_SIZE(
t.signers
) > 1 THEN t.signers [1] :: STRING
ELSE NULL
END AS potential_nft_mint,
t.succeeded,
silver.udf_get_all_inner_instruction_events(
inner_instruction :instructions
) AS inner_instruction_events
FROM
{{ ref('silver__events') }}
e
INNER JOIN {{ ref('silver__transactions') }}
t
ON t.tx_id = e.tx_id
WHERE
(event_type IN ('mintTo', 'initializeMint')
OR (program_id = 'CMZYPASGWeTz7RNGHaRJfCq2XQ5pYK6nDvVQxzkH51zb'
AND (ARRAY_CONTAINS('mintTo' :: variant, inner_instruction_events)
OR ARRAY_CONTAINS('initializeMint' :: variant, inner_instruction_events))))
{% if is_incremental() %}
AND e._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
AND t._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
mint_tx AS (
SELECT
DISTINCT tx_id,
signer,
potential_nft_mint,
succeeded
FROM
mint_tx_tmp
),
txs_tmp AS (
SELECT
e.block_timestamp,
e.block_id,
t.tx_id,
t.succeeded AS succeeded,
t.signer,
t.potential_nft_mint,
program_id,
e.index,
i.index AS inner_index,
COALESCE(
i.value :parsed :info :lamports :: INTEGER,
i.value :parsed :info :amount :: INTEGER
) AS sales_amount,
LAST_VALUE(
i.value :parsed :info :mint :: STRING ignore nulls
) over (
PARTITION BY t.tx_id,
e.index
ORDER BY
inner_index
) AS nft,
LAST_VALUE(
i.value :parsed :info :multisigAuthority :: STRING ignore nulls
) over (
PARTITION BY t.tx_id,
e.index
ORDER BY
inner_index
) AS wallet,
i.value :parsed :info :authority :: STRING AS authority,
i.value :parsed :info :source :: STRING AS source,
i.value: parsed :info :destination :: STRING AS destination,
CASE
-- marindate specific
WHEN e.inner_instruction :instructions [0] :programId :: STRING = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s' THEN e.instruction :accounts [3] :: STRING
ELSE NULL
END AS update_authority,
e.ingested_at,
e._inserted_timestamp
FROM
{{ ref('silver__events') }}
e
INNER JOIN mint_tx t
ON t.tx_id = e.tx_id
LEFT OUTER JOIN TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
e.event_type IS NULL
AND (
ARRAY_CONTAINS(
'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s' :: variant,
e.instruction :accounts :: ARRAY
)
OR e.inner_instruction :instructions [0] :programId :: STRING = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
OR e.program_id IN (
'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s',
'CMZYPASGWeTz7RNGHaRJfCq2XQ5pYK6nDvVQxzkH51zb'
)
)
AND t.succeeded = TRUE
{% if is_incremental() %}
AND e._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
txs AS (
SELECT
*
FROM
txs_tmp
WHERE
(
program_id NOT IN (
'342zaQ1jgejKvPMqcnZejuZ845NtnfkpGvo9j15gDmEL',
'TTTi5K2DS4qD95yyvvWht53qFWT8ff1Hp3xKsrp1QQf'
)
OR (
program_id IN (
'342zaQ1jgejKvPMqcnZejuZ845NtnfkpGvo9j15gDmEL',
'TTTi5K2DS4qD95yyvvWht53qFWT8ff1Hp3xKsrp1QQf'
)
AND wallet IS NULL
)
)
),
transfers AS (
SELECT
tr.*
FROM
{{ ref('silver__transfers') }}
tr
INNER JOIN mint_tx t
ON t.tx_id = tr.tx_id
{% if is_incremental() %}
WHERE
tr._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
mint_currency AS (
SELECT
DISTINCT t.tx_id,
p.mint AS mint_paid,
p.account,
p.decimal
FROM
txs t
INNER JOIN {{ ref('silver___post_token_balances') }}
p
ON t.tx_id = p.tx_id
WHERE
source = p.account
{% if is_incremental() %}
AND p._inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
),
pre_final AS (
SELECT
block_timestamp,
block_id,
t.tx_id,
succeeded,
program_id,
CASE
WHEN program_id = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s' THEN COALESCE(
signer,
wallet
)
ELSE COALESCE(
wallet,
signer
)
END AS purchaser,
CASE
WHEN update_authority = '6jG2QcwaJPFS8Y9SzgH2kfKPj6ERhLi9RVtH8kRahj4j' THEN -- marinade nfts are "free"
0
ELSE SUM(sales_amount / pow(10, COALESCE(p.decimal, 9)))
END AS mint_price,
COALESCE(
p.mint_paid,
'So11111111111111111111111111111111111111111'
) AS mint_currency,
COALESCE(
nft,
potential_nft_mint
) AS mint,
ingested_at,
_inserted_timestamp
FROM
txs t
LEFT OUTER JOIN mint_currency p
ON p.tx_id = t.tx_id
AND p.account = t.source
WHERE
sales_amount IS NOT NULL
AND destination IS NOT NULL
GROUP BY
block_timestamp,
block_id,
t.tx_id,
program_id,
purchaser,
succeeded,
mint_currency,
mint,
update_authority,
ingested_at,
_inserted_timestamp
),
pre_pre_final AS (
SELECT
pf.block_timestamp,
pf.block_id,
pf.tx_id,
pf.program_id,
pf.purchaser,
pf.succeeded,
CASE
WHEN tr.tx_id IS NOT NULL
AND mint_currency = 'So11111111111111111111111111111111111111111' THEN mint_price + tr.amount
ELSE mint_price
END AS mint_price,
pf.mint_currency,
pf.mint,
pf.ingested_at,
pf._inserted_timestamp
FROM
pre_final pf
LEFT OUTER JOIN transfers tr
ON tr.tx_id = pf.tx_id
AND tr.tx_from = pf.purchaser
AND pf.program_id = 'CMZYPASGWeTz7RNGHaRJfCq2XQ5pYK6nDvVQxzkH51zb'
)
SELECT
*
FROM
pre_pre_final
WHERE
program_id <> 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
UNION
SELECT
block_timestamp,
block_id,
tx_id,
program_id,
purchaser,
succeeded,
SUM(mint_price) over (
PARTITION BY tx_id,
purchaser,
mint,
mint_currency
) AS mint_price,
mint_currency,
mint,
ingested_at,
_inserted_timestamp
FROM
pre_pre_final
WHERE
program_id = 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
AND tx_id NOT IN (
SELECT
DISTINCT tx_id
FROM
pre_pre_final
WHERE
program_id <> 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'
)
AND mint IS NOT NULL qualify(ROW_NUMBER() over (PARTITION BY tx_id, purchaser, mint, mint_currency
ORDER BY
block_id)) = 1

View File

@ -0,0 +1,74 @@
{{ config(
materialized = 'incremental',
unique_key = "CONCAT_WS('-', tx_id, event_type, mint)",
incremental_strategy = 'delete+insert',
cluster_by = ['block_timestamp::DATE','_inserted_timestamp::DATE'],
) }}
WITH base_events AS (
SELECT
*
FROM
{{ ref('silver__events') }}
{% if is_incremental() %}
WHERE
_inserted_timestamp >= (
SELECT
MAX(_inserted_timestamp)
FROM
{{ this }}
)
{% endif %}
)
SELECT
block_id,
block_timestamp,
tx_id,
succeeded,
index,
null as inner_index,
event_type,
instruction :parsed :info :mint :: STRING AS mint,
instruction :parsed :info :decimals :: INTEGER AS DECIMAL,
COALESCE(
instruction :parsed :info :amount :: INTEGER,
instruction :parsed :info :tokenAmount: amount :: INTEGER
) AS mint_amount,
_inserted_timestamp
FROM
base_events
WHERE
event_type IN (
'mintTo',
'initializeMint',
'mintToChecked',
'initializeMint2'
)
UNION
SELECT
block_id,
block_timestamp,
tx_id,
succeeded,
e.index,
i.index as inner_index,
i.value :parsed :type :: STRING AS event_type,
i.value :parsed :info :mint :: STRING AS mint,
i.value :parsed :info :decimals :: INTEGER AS DECIMAL,
COALESCE(
i.value :parsed :info :amount :: INTEGER,
i.value :parsed :info :tokenAmount: amount :: INTEGER
) AS mint_amount,
_inserted_timestamp
FROM
base_events e,
TABLE(FLATTEN(inner_instruction :instructions)) i
WHERE
i.value :parsed :type :: STRING IN (
'mintTo',
'initializeMint',
'mintToChecked',
'initializeMint2'
)

View File

@ -0,0 +1,60 @@
version: 2
models:
- name: silver__mint_actions
description: table holding mint initialization or token minting events
tests:
- dbt_utils.unique_combination_of_columns:
combination_of_columns:
- TX_ID
- INDEX
- INNER_INDEX
- EVENT_TYPE
- MINT
columns:
- name: BLOCK_TIMESTAMP
description: "{{ doc('block_timestamp') }}"
tests:
- not_null
- dbt_expectations.expect_row_values_to_have_recent_data:
datepart: day
interval: 3
- name: BLOCK_ID
description: "{{ doc('block_id') }}"
tests:
- not_null
- name: TX_ID
description: "{{ doc('tx_id') }}"
tests:
- not_null
- name: SUCCEEDED
description: "{{ doc('tx_succeeded') }}"
tests:
- not_null
- name: INDEX
description: "{{ doc('event_index') }}"
tests:
- not_null
- name: INNER_INDEX
description: Location of the inner instruction within an instruction
- name: EVENT_TYPE
description: "{{ doc('event_type') }}"
tests:
- not_null
- name: MINT
description: "{{ doc('mint') }}"
tests:
- not_null
- name: DECIMAL
description: "{{ doc('decimal') }}"
tests:
- not_null:
where: event_type in ('initializeMint','initializeMint2')
- name: MINT_AMOUNT
description: "{{ doc('mint_amount') }}"
tests:
- not_null:
where: event_type in ('mintTo','mintToChecked')
- name: _INSERTED_TIMESTAMP
description: "{{ doc('_inserted_timestamp') }}"
tests:
- not_null