diff --git a/.github/workflows/_move_tests.yml b/.github/workflows/_move_tests.yml
index a98c7ad8f3f..54c8b002f08 100644
--- a/.github/workflows/_move_tests.yml
+++ b/.github/workflows/_move_tests.yml
@@ -26,4 +26,24 @@ jobs:
tool: nextest
- name: Run move tests
run: |
- cargo nextest run -p iota-framework-tests -- unit_tests::
+ cargo nextest run -E
+ 'package(iota-framework-tests)
+ or (package(iota-core) and test(quorum_driver::))
+ or package(iota-benchmark)
+ or test(move_tests::)'
+
+ move-simtest:
+ timeout-minutes: 10
+ runs-on: [self-hosted]
+ steps:
+ - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1
+ - uses: taiki-e/install-action@375e0c7f08a66b8c2ba7e7eef31a6f91043a81b0 # v2.44.38
+ with:
+ tool: nextest
+ - name: Run move tests
+ run: |
+ scripts/simtest/cargo-simtest simtest --profile ci -E
+ 'package(iota-framework-tests)
+ or (package(iota-core) and test(quorum_driver::))
+ or package(iota-benchmark)
+ or test(move_tests::)'
diff --git a/.github/workflows/_vercel_deploy.yml b/.github/workflows/_vercel_deploy.yml
index d85f6664fff..ffdb8fda37f 100644
--- a/.github/workflows/_vercel_deploy.yml
+++ b/.github/workflows/_vercel_deploy.yml
@@ -68,14 +68,16 @@ jobs:
secrets: inherit
with:
isProd: false
+ isStaging: false
- wallet-dashboard-prod:
- name: Vercel Wallet Dashboard Production
+ wallet-dashboard-staging:
+ name: Vercel Wallet Dashboard Staging
if: github.ref_name == 'develop'
uses: ./.github/workflows/apps_wallet_dashboard_deploy.yml
secrets: inherit
with:
- isProd: true
+ isProd: false
+ isStaging: true
apps-backend-preview:
name: Vercel apps-backend Preview
diff --git a/.github/workflows/apps_wallet_dashboard_deploy.yml b/.github/workflows/apps_wallet_dashboard_deploy.yml
index d3ae3f5f284..f533776b7bb 100644
--- a/.github/workflows/apps_wallet_dashboard_deploy.yml
+++ b/.github/workflows/apps_wallet_dashboard_deploy.yml
@@ -3,14 +3,25 @@ name: Deploy for Wallet Dashboard
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.WALLET_DASHBOARD_VERCEL_PROJECT_ID }}
+ WALLET_DASHBOARD_VERCEL_PROJECT_STAGING_URL: ${{ secrets.WALLET_DASHBOARD_VERCEL_PROJECT_STAGING_URL }}
on:
workflow_dispatch:
+ inputs:
+ isProd:
+ type: boolean
+ required: true
+ isStaging:
+ type: boolean
+ required: true
workflow_call:
inputs:
isProd:
type: boolean
required: true
+ isStaging:
+ type: boolean
+ required: true
jobs:
deploy:
@@ -64,8 +75,11 @@ jobs:
id: deploy_url
if: ${{ inputs.isProd == false }}
run: echo "DEPLOY_URL=$(cat vercel_output.txt | awk 'END{print}')" >> $GITHUB_OUTPUT
+ - name: Alias Staging deploy
+ if: ${{ inputs.isStaging }}
+ run: vercel alias ${{ steps.deploy_url.outputs.DEPLOY_URL }} $WALLET_DASHBOARD_VERCEL_PROJECT_STAGING_URL --token=${{ secrets.VERCEL_TOKEN }} --scope=${{ secrets.VERCEL_SCOPE }}
- name: Comment on pull request
- if: ${{ inputs.isProd == false }}
+ if: ${{ inputs.isProd == false && inputs.isStaging == false }}
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/apps_wallet_prod_build.yml b/.github/workflows/apps_wallet_prod_build.yml
index f4714cd53e1..9a8052331d8 100644
--- a/.github/workflows/apps_wallet_prod_build.yml
+++ b/.github/workflows/apps_wallet_prod_build.yml
@@ -20,6 +20,11 @@ jobs:
steps:
- name: Checking out the repository
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
+ with:
+ # Number of commits to fetch. 0 indicates all history for all branches and tags. Default: 1
+ fetch-depth: 0
+ # Whether to fetch tags, even if fetch-depth > 0.
+ fetch-tags: "true"
- uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- name: Install Nodejs
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
@@ -61,8 +66,9 @@ jobs:
echo "No previous tag found. Skipping changelog generation."
echo "changelog=No previous tag found. Changelog generation skipped." >> $GITHUB_OUTPUT
else
- echo "## Changelog" >> CHANGELOG.md
- git log ${{ env.PREV_TAG }}..${{ env.CURRENT_TAG }} --pretty=format:"- %s in #%h" -- ./apps/wallet > CHANGELOG.md
+ echo "## Changelog" > CHANGELOG.md
+ git log ${{ env.PREV_TAG }}..${{ env.CURRENT_TAG }} --pretty=format:"- %s in #%h" -- ./apps/wallet >> CHANGELOG.md
+ cat CHANGELOG.md
fi
- name: Get version from tag
diff --git a/Cargo.lock b/Cargo.lock
index c0b1c6e29bf..550aa462be0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -803,7 +803,7 @@ dependencies = [
"proc-macro2 1.0.86",
"quote 1.0.37",
"syn 1.0.109",
- "synstructure",
+ "synstructure 0.12.6",
]
[[package]]
@@ -5500,6 +5500,124 @@ dependencies = [
"cc",
]
+[[package]]
+name = "icu_collections"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_locid_transform_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
+
+[[package]]
+name = "icu_normalizer"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "utf16_iter",
+ "utf8_iter",
+ "write16",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+
+[[package]]
+name = "icu_properties"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locid_transform",
+ "icu_properties_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+
+[[package]]
+name = "icu_provider"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.37",
+ "syn 2.0.77",
+]
+
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -5508,12 +5626,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
-version = "0.5.0"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
dependencies = [
- "unicode-bidi",
- "unicode-normalization",
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
]
[[package]]
@@ -8275,7 +8404,7 @@ version = "0.8.0-alpha"
dependencies = [
"proc-macro2 1.0.86",
"syn 1.0.109",
- "synstructure",
+ "synstructure 0.12.6",
]
[[package]]
@@ -8876,7 +9005,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
dependencies = [
"cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets 0.48.5",
]
[[package]]
@@ -8972,6 +9101,12 @@ version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+[[package]]
+name = "litemap"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104"
+
[[package]]
name = "lock_api"
version = "0.4.12"
@@ -10066,7 +10201,7 @@ dependencies = [
"proc-macro2 1.0.86",
"quote 1.0.37",
"syn 1.0.109",
- "synstructure",
+ "synstructure 0.12.6",
]
[[package]]
@@ -11040,9 +11175,9 @@ dependencies = [
[[package]]
name = "passkey-authenticator"
-version = "0.2.0"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4017d27e98940a98358b43a3fe19cb3d7b7c821c3b35634d8087230e92445579"
+checksum = "f9b065ce31354bcf23a333003c77f0d71f00eb95761b3390a069546e078a7a5b"
dependencies = [
"async-trait",
"coset",
@@ -11054,9 +11189,9 @@ dependencies = [
[[package]]
name = "passkey-client"
-version = "0.2.0"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f14d42b14749cc7927add34a9932b3b3cc5349a633384850baa67183061439dd"
+checksum = "5080bfafe23d139ae8be8b907453aee0b8af3ca7cf25d1f8d7bfcf7b079d3412"
dependencies = [
"ciborium",
"coset",
@@ -11072,14 +11207,16 @@ dependencies = [
[[package]]
name = "passkey-types"
-version = "0.2.0"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "499cff8432e71c5f8784d9645aac0f9fca604d67f59b68a606170b5e229c6538"
+checksum = "77144664f6aac5f629d7efa815f5098a054beeeca6ccafee5ec453fd2b0c53f9"
dependencies = [
"bitflags 2.6.0",
"ciborium",
"coset",
"data-encoding",
+ "getrandom 0.2.15",
+ "hmac",
"indexmap 2.5.0",
"rand 0.8.5",
"serde",
@@ -11087,6 +11224,7 @@ dependencies = [
"sha2 0.10.8",
"strum 0.25.0",
"typeshare",
+ "zeroize",
]
[[package]]
@@ -14337,6 +14475,17 @@ dependencies = [
"unicode-xid 0.2.6",
]
+[[package]]
+name = "synstructure"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.37",
+ "syn 2.0.77",
+]
+
[[package]]
name = "sysinfo"
version = "0.31.4"
@@ -14710,6 +14859,16 @@ dependencies = [
"crunchy",
]
+[[package]]
+name = "tinystr"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
[[package]]
name = "tinytemplate"
version = "1.2.1"
@@ -15338,7 +15497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
"cfg-if",
- "rand 0.8.5",
+ "rand 0.7.3",
"static_assertions",
]
@@ -15466,12 +15625,6 @@ dependencies = [
"version_check",
]
-[[package]]
-name = "unicode-bidi"
-version = "0.3.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
-
[[package]]
name = "unicode-ident"
version = "1.0.13"
@@ -15563,9 +15716,9 @@ dependencies = [
[[package]]
name = "url"
-version = "2.5.2"
+version = "2.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c"
+checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
dependencies = [
"form_urlencoded",
"idna",
@@ -15585,6 +15738,18 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+[[package]]
+name = "utf16_iter"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
[[package]]
name = "utf8parse"
version = "0.2.2"
@@ -16218,6 +16383,18 @@ dependencies = [
"windows-sys 0.48.0",
]
+[[package]]
+name = "write16"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
+
+[[package]]
+name = "writeable"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+
[[package]]
name = "ws_stream_wasm"
version = "0.7.4"
@@ -16328,6 +16505,30 @@ dependencies = [
"time",
]
+[[package]]
+name = "yoke"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.37",
+ "syn 2.0.77",
+ "synstructure 0.13.1",
+]
+
[[package]]
name = "yup-oauth2"
version = "8.3.2"
@@ -16376,6 +16577,27 @@ dependencies = [
"syn 2.0.77",
]
+[[package]]
+name = "zerofrom"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.37",
+ "syn 2.0.77",
+ "synstructure 0.13.1",
+]
+
[[package]]
name = "zeroize"
version = "1.8.1"
@@ -16397,6 +16619,28 @@ dependencies = [
"syn 2.0.77",
]
+[[package]]
+name = "zerovec"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+dependencies = [
+ "proc-macro2 1.0.86",
+ "quote 1.0.37",
+ "syn 2.0.77",
+]
+
[[package]]
name = "zip"
version = "0.6.6"
diff --git a/Cargo.toml b/Cargo.toml
index 277ac3a5492..9dbfc1385f2 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -284,9 +284,9 @@ object_store = { version = "0.10", features = ["aws", "gcp", "azure", "http"] }
once_cell = "1.18.0"
p256 = { version = "0.13.2", features = ["ecdsa"] }
parking_lot = "0.12.1"
-passkey-authenticator = { version = "0.2.0" }
-passkey-client = { version = "0.2.0" }
-passkey-types = { version = "0.2.0" }
+passkey-authenticator = "0.4.0"
+passkey-client = "0.4.0"
+passkey-types = "0.4.0"
pretty_assertions = "1.3.0"
proc-macro2 = "1.0.47"
prometheus = "0.13.3"
diff --git a/apps/core/src/components/stake/StakedCard.tsx b/apps/core/src/components/stake/StakedCard.tsx
index 58bc5c82f20..92f6b0e8184 100644
--- a/apps/core/src/components/stake/StakedCard.tsx
+++ b/apps/core/src/components/stake/StakedCard.tsx
@@ -37,7 +37,7 @@ export function StakedCard({
// For inactive validator, show principal + rewards
const [principalStaked, symbol] = useFormatCoin(
- inactiveValidator ? principal + rewards : principal,
+ inactiveValidator ? BigInt(principal) + rewards : principal,
IOTA_TYPE_ARG,
);
diff --git a/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx b/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx
index bb69cf69226..94e120821d3 100644
--- a/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx
+++ b/apps/core/src/components/transaction/info/UnstakeTransactionInfo.tsx
@@ -27,21 +27,21 @@ export function UnstakeTransactionInfo({
renderExplorerLink,
}: UnstakeTransactionInfoProps) {
const json = event.parsedJson as {
- principal_amount?: number;
- reward_amount?: number;
+ principal_amount?: string;
+ reward_amount?: string;
validator_address?: string;
};
- const principalAmount = json?.principal_amount || 0;
- const rewardAmount = json?.reward_amount || 0;
+ const principalAmount = json?.principal_amount || '0';
+ const rewardAmount = json?.reward_amount || '0';
const validatorAddress = json?.validator_address;
- const totalAmount = Number(principalAmount) + Number(rewardAmount);
+ const totalAmount = BigInt(principalAmount) + BigInt(rewardAmount);
const [formatPrinciple, symbol] = useFormatCoin(principalAmount, IOTA_TYPE_ARG);
const [formatRewards] = useFormatCoin(rewardAmount || 0, IOTA_TYPE_ARG);
return (
{validatorAddress &&
}
- {totalAmount && (
+ {totalAmount !== 0n && (
)}
diff --git a/apps/core/src/constants/coins.constants.ts b/apps/core/src/constants/coins.constants.ts
index 11fba0c12a0..b0e38e586cd 100644
--- a/apps/core/src/constants/coins.constants.ts
+++ b/apps/core/src/constants/coins.constants.ts
@@ -3,3 +3,4 @@
export const COINS_QUERY_REFETCH_INTERVAL = 20_000;
export const COINS_QUERY_STALE_TIME = 20_000;
+export const COIN_TYPE = '0x2::coin::Coin';
diff --git a/apps/core/src/hooks/useCountdownByTimestamp.ts b/apps/core/src/hooks/useCountdownByTimestamp.ts
index 3b79b69b915..18a5a598292 100644
--- a/apps/core/src/hooks/useCountdownByTimestamp.ts
+++ b/apps/core/src/hooks/useCountdownByTimestamp.ts
@@ -9,7 +9,17 @@ import {
MILLISECONDS_PER_SECOND,
} from '../constants';
-export function useCountdownByTimestamp(initialTimestamp: number | null): string {
+interface FormatCountdownOptions {
+ showSeconds?: boolean;
+ showMinutes?: boolean;
+ showHours?: boolean;
+ showDays?: boolean;
+}
+
+export function useCountdownByTimestamp(
+ initialTimestamp: number | null,
+ options?: FormatCountdownOptions,
+): string {
const [timeRemainingMs, setTimeRemainingMs] = useState(0);
useEffect(() => {
@@ -22,11 +32,19 @@ export function useCountdownByTimestamp(initialTimestamp: number | null): string
return () => clearInterval(interval);
}, [initialTimestamp]);
- const formattedCountdown = formatCountdown(timeRemainingMs);
+ const formattedCountdown = formatCountdown(timeRemainingMs, options);
return formattedCountdown;
}
-function formatCountdown(totalMilliseconds: number) {
+function formatCountdown(
+ totalMilliseconds: number,
+ {
+ showSeconds = true,
+ showMinutes = true,
+ showHours = true,
+ showDays = true,
+ }: FormatCountdownOptions = {},
+) {
const days = Math.floor(totalMilliseconds / MILLISECONDS_PER_DAY);
const hours = Math.floor((totalMilliseconds % MILLISECONDS_PER_DAY) / MILLISECONDS_PER_HOUR);
const minutes = Math.floor(
@@ -36,11 +54,11 @@ function formatCountdown(totalMilliseconds: number) {
(totalMilliseconds % MILLISECONDS_PER_MINUTE) / MILLISECONDS_PER_SECOND,
);
- const timeUnits = [];
- if (days > 0) timeUnits.push(`${days}d`);
- if (hours > 0) timeUnits.push(`${hours}h`);
- if (minutes > 0) timeUnits.push(`${minutes}m`);
- if (seconds > 0 || timeUnits.length === 0) timeUnits.push(`${seconds}s`);
+ const timeUnits: string[] = [];
+ if (showDays && days > 0) timeUnits.push(`${days}d`);
+ if (showHours && hours > 0) timeUnits.push(`${hours}h`);
+ if (showMinutes && minutes > 0) timeUnits.push(`${minutes}m`);
+ if (showSeconds && (seconds > 0 || timeUnits.length === 0)) timeUnits.push(`${seconds}s`);
return timeUnits.join(' ');
}
diff --git a/apps/core/src/utils/getStakeIotaByIotaId.ts b/apps/core/src/utils/getStakeIotaByIotaId.ts
index 5bdaa2a01ee..ba2e8837c99 100644
--- a/apps/core/src/utils/getStakeIotaByIotaId.ts
+++ b/apps/core/src/utils/getStakeIotaByIotaId.ts
@@ -10,7 +10,7 @@ export function getStakeIotaByIotaId(allDelegation: DelegatedStake[], stakeIotaI
allDelegation.reduce((acc, curr) => {
const total = BigInt(
curr.stakes.find(({ stakedIotaId }) => stakedIotaId === stakeIotaId)?.principal ||
- 0,
+ 0n,
);
return total + acc;
}, 0n) || 0n
diff --git a/apps/explorer/src/components/home-metrics/OnTheNetwork.tsx b/apps/explorer/src/components/home-metrics/OnTheNetwork.tsx
index d98dc4b126f..35bd6468232 100644
--- a/apps/explorer/src/components/home-metrics/OnTheNetwork.tsx
+++ b/apps/explorer/src/components/home-metrics/OnTheNetwork.tsx
@@ -98,7 +98,7 @@ export function OnTheNetwork(): JSX.Element {
size={LabelTextSize.Large}
label="Reference Gas Price"
text={gasPriceFormatted ?? '-'}
- supportingLabel={gasPriceFormatted !== null ? 'IOTA' : undefined}
+ supportingLabel={gasPriceFormatted !== null ? 'nano' : undefined}
tooltipPosition={TooltipPosition.Top}
tooltipText="The reference gas price in the current epoch."
/>
diff --git a/apps/explorer/src/components/network/NetworkSelector.tsx b/apps/explorer/src/components/network/NetworkSelector.tsx
index 34da8635f62..deb20e35e9b 100644
--- a/apps/explorer/src/components/network/NetworkSelector.tsx
+++ b/apps/explorer/src/components/network/NetworkSelector.tsx
@@ -99,11 +99,12 @@ export function NetworkSelector(): JSX.Element {
key={idx}
onClick={() => handleNetworkSwitch(network.id)}
hideBottomBorder
+ isHighlighted={network === selectedNetwork}
>
diff --git a/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx b/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx
index 2f4f653a9cc..bd777c19e41 100644
--- a/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx
+++ b/apps/explorer/src/components/top-validators-card/TopValidatorsCard.tsx
@@ -3,9 +3,18 @@
// SPDX-License-Identifier: Apache-2.0
import { useIotaClientQuery } from '@iota/dapp-kit';
-import { PlaceholderTable, TableCard } from '~/components/ui';
+import { Link, PlaceholderTable, TableCard } from '~/components/ui';
import { generateValidatorsTableColumns } from '~/lib/ui';
-import { InfoBox, InfoBoxStyle, InfoBoxType, Panel, Title } from '@iota/apps-ui-kit';
+import {
+ Button,
+ ButtonSize,
+ ButtonType,
+ InfoBox,
+ InfoBoxStyle,
+ InfoBoxType,
+ Panel,
+ Title,
+} from '@iota/apps-ui-kit';
import { ErrorBoundary } from '../error-boundary/ErrorBoundary';
import { Warning } from '@iota/ui-icons';
@@ -19,6 +28,9 @@ type TopValidatorsCardProps = {
export function TopValidatorsCard({ limit, showIcon }: TopValidatorsCardProps): JSX.Element {
const { data, isPending, isSuccess, isError } = useIotaClientQuery('getLatestIotaSystemState');
+ const topActiveValidators =
+ data?.activeValidators.slice(0, limit || NUMBER_OF_VALIDATORS) ?? [];
+
const tableColumns = generateValidatorsTableColumns({
atRiskValidators: [],
validatorEvents: [],
@@ -42,26 +54,33 @@ export function TopValidatorsCard({ limit, showIcon }: TopValidatorsCardProps):
return (
-
-
-
- {isPending && (
-
- )}
+
+
+
+
+
+
+
- {isSuccess && (
-
-
+ {isPending && (
+
-
- )}
+ )}
+
+ {isSuccess && (
+
+
+
+ )}
+
);
diff --git a/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts b/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts
index 92e2e32d939..e239ce3a86e 100644
--- a/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts
+++ b/apps/explorer/src/pages/transaction-result/programmable-transaction-view/utils.ts
@@ -24,10 +24,11 @@ export function flattenIotaArguments(data: (IotaArgument | IotaArgument[])[]): s
} else if ('NestedResult' in value) {
return `NestedResult(${value.NestedResult[0]}, ${value.NestedResult[1]})`;
}
+ } else if (typeof value === 'string') {
+ return value;
} else {
throw new Error('Not a correct flattenable data');
}
- return '';
})
.join(', ');
}
diff --git a/apps/ui-kit/package.json b/apps/ui-kit/package.json
index ff323347fea..89e9785c466 100644
--- a/apps/ui-kit/package.json
+++ b/apps/ui-kit/package.json
@@ -66,7 +66,7 @@
"tailwindcss": "^3.3.3",
"typescript": "^5.5.3",
"vite": "^5.3.3",
- "vite-plugin-dts": "^3.9.1",
+ "vite-plugin-dts": "^4.3.0",
"vite-tsconfig-paths": "^4.2.0"
}
}
diff --git a/apps/ui-kit/src/lib/components/atoms/list-item/ListItem.tsx b/apps/ui-kit/src/lib/components/atoms/list-item/ListItem.tsx
index 2a5806cf08f..9f6475a674b 100644
--- a/apps/ui-kit/src/lib/components/atoms/list-item/ListItem.tsx
+++ b/apps/ui-kit/src/lib/components/atoms/list-item/ListItem.tsx
@@ -23,6 +23,10 @@ export interface ListItemProps {
* The list item is disabled or not.
*/
isDisabled?: boolean;
+ /**
+ * The list item is highlighted.
+ */
+ isHighlighted?: boolean;
}
export function ListItem({
@@ -31,6 +35,7 @@ export function ListItem({
onClick,
isDisabled,
children,
+ isHighlighted,
}: PropsWithChildren
): React.JSX.Element {
function handleKeyDown(event: React.KeyboardEvent) {
if ((event.key === 'Enter' || event.key === ' ') && !isDisabled && onClick) {
@@ -63,7 +68,10 @@ export function ListItem({
className={cx(
'relative flex flex-row items-center justify-between px-md py-sm text-neutral-10 dark:text-neutral-92',
!isDisabled && onClick ? 'cursor-pointer' : 'cursor-default',
- { 'state-layer': !isDisabled },
+ {
+ 'bg-shader-primary-dark-16 dark:bg-shader-inverted-dark-16': isHighlighted,
+ 'state-layer': !isDisabled,
+ },
)}
>
{children}
diff --git a/apps/wallet-dashboard/app/(protected)/assets/page.tsx b/apps/wallet-dashboard/app/(protected)/assets/page.tsx
index ed96fe0a519..9af8669a717 100644
--- a/apps/wallet-dashboard/app/(protected)/assets/page.tsx
+++ b/apps/wallet-dashboard/app/(protected)/assets/page.tsx
@@ -4,7 +4,7 @@
'use client';
import { Panel, Title, Chip, TitleSize } from '@iota/apps-ui-kit';
-import { hasDisplayData, useGetOwnedObjects } from '@iota/core';
+import { COIN_TYPE, hasDisplayData, useGetOwnedObjects } from '@iota/core';
import { useCurrentAccount } from '@iota/dapp-kit';
import { IotaObjectData } from '@iota/iota-sdk/client';
import { useState } from 'react';
@@ -29,27 +29,30 @@ export default function AssetsDashboardPage(): React.JSX.Element {
const [selectedAsset, setSelectedAsset] = useState(null);
const [selectedCategory, setSelectedCategory] = useState(AssetCategory.Visual);
const account = useCurrentAccount();
- const { data, isFetching, fetchNextPage, hasNextPage } = useGetOwnedObjects(
+ const { data, isFetching, fetchNextPage, hasNextPage, refetch } = useGetOwnedObjects(
account?.address,
- undefined,
+ {
+ MatchNone: [{ StructType: COIN_TYPE }],
+ },
OBJECTS_PER_REQ,
);
- const assets: IotaObjectData[] = [];
-
- for (const page of data?.pages || []) {
- for (const asset of page.data) {
- if (asset.data && asset.data.objectId) {
- if (selectedCategory == AssetCategory.Visual) {
- if (hasDisplayData(asset)) {
- assets.push(asset.data);
- }
- } else if (selectedCategory == AssetCategory.Other) {
- assets.push(asset.data);
- }
+ const assets = (data?.pages || [])
+ .flatMap((page) => page.data)
+ .filter((asset) => {
+ if (!asset.data || !asset.data.objectId) {
+ return false;
}
- }
- }
+ if (selectedCategory === AssetCategory.Visual) {
+ return hasDisplayData(asset);
+ }
+ if (selectedCategory === AssetCategory.Other) {
+ return !hasDisplayData(asset);
+ }
+ return false;
+ })
+ .map((asset) => asset.data)
+ .filter((data): data is IotaObjectData => data !== null && data !== undefined);
function onAssetClick(asset: IotaObjectData) {
setSelectedAsset(asset);
@@ -79,7 +82,11 @@ export default function AssetsDashboardPage(): React.JSX.Element {
fetchNextPage={fetchNextPage}
/>
{selectedAsset && (
- setSelectedAsset(null)} asset={selectedAsset} />
+ setSelectedAsset(null)}
+ asset={selectedAsset}
+ refetchAssets={refetch}
+ />
)}
diff --git a/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx b/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx
index 2fe8eba32f3..3b802387ca8 100644
--- a/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx
+++ b/apps/wallet-dashboard/app/(protected)/components/top-nav/TopNav.tsx
@@ -1,18 +1,43 @@
// Copyright (c) 2024 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0
+import { SettingsDialog, useSettingsDialog } from '@/components';
import { Badge, BadgeType, Button, ButtonType } from '@iota/apps-ui-kit';
+import { ConnectButton, useIotaClientContext } from '@iota/dapp-kit';
+import { getNetwork, Network } from '@iota/iota-sdk/client';
import { ThemeSwitcher } from '@iota/core';
-import { ConnectButton } from '@iota/dapp-kit';
import { Settings } from '@iota/ui-icons';
export function TopNav() {
+ const { network } = useIotaClientContext();
+ const { name: networkName } = getNetwork(network);
+ const {
+ isSettingsDialogOpen,
+ settingsDialogView,
+ setSettingsDialogView,
+ onCloseSettingsDialogClick,
+ onOpenSettingsDialogClick,
+ } = useSettingsDialog();
+
return (
-
+
+
- } type={ButtonType.Ghost} />
+ }
+ type={ButtonType.Ghost}
+ onClick={onOpenSettingsDialogClick}
+ />
);
}
diff --git a/apps/wallet-dashboard/app/(protected)/home/page.tsx b/apps/wallet-dashboard/app/(protected)/home/page.tsx
index 61f55475702..d435d44f630 100644
--- a/apps/wallet-dashboard/app/(protected)/home/page.tsx
+++ b/apps/wallet-dashboard/app/(protected)/home/page.tsx
@@ -8,6 +8,7 @@ import {
TransactionsOverview,
StakingOverview,
MigrationOverview,
+ SupplyIncreaseVestingOverview,
} from '@/components';
import { useFeature } from '@growthbook/growthbook-react';
import { Feature } from '@iota/core';
@@ -18,12 +19,13 @@ function HomeDashboardPage(): JSX.Element {
const account = useCurrentAccount();
const stardustMigrationEnabled = useFeature
(Feature.StardustMigration).value;
+ const supplyIncreaseVestingEnabled = useFeature(Feature.SupplyIncreaseVesting).value;
return (
{connectionStatus === 'connected' && account && (
<>
-
+
@@ -31,12 +33,10 @@ function HomeDashboardPage(): JSX.Element {
{stardustMigrationEnabled &&
}
-
+
-
- Vesting
-
+ {supplyIncreaseVestingEnabled &&
}
diff --git a/apps/wallet-dashboard/app/(protected)/migrations/page.tsx b/apps/wallet-dashboard/app/(protected)/migrations/page.tsx
index acc5dd6f40c..e2cd767e663 100644
--- a/apps/wallet-dashboard/app/(protected)/migrations/page.tsx
+++ b/apps/wallet-dashboard/app/(protected)/migrations/page.tsx
@@ -6,9 +6,8 @@
import { useState, useMemo, useCallback } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import clsx from 'clsx';
-import MigratePopup from '@/components/Popup/Popups/MigratePopup';
-import { useGetStardustMigratableObjects, usePopups } from '@/hooks';
-import { summarizeMigratableObjectValues, summarizeUnmigratableObjectValues } from '@/lib/utils';
+import { useGetStardustMigratableObjects } from '@/hooks';
+import { summarizeMigratableObjectValues, summarizeTimelockedObjectValues } from '@/lib/utils';
import {
Button,
ButtonSize,
@@ -25,15 +24,16 @@ import { useCurrentAccount, useIotaClient } from '@iota/dapp-kit';
import { STARDUST_BASIC_OUTPUT_TYPE, STARDUST_NFT_OUTPUT_TYPE, useFormatCoin } from '@iota/core';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { StardustOutputMigrationStatus } from '@/lib/enums';
-import { MigrationObjectsPanel } from '@/components';
+import { MigrationObjectsPanel, MigrationDialog } from '@/components';
+import { useRouter } from 'next/navigation';
function MigrationDashboardPage(): JSX.Element {
const account = useCurrentAccount();
const address = account?.address || '';
- const { openPopup, closePopup } = usePopups();
const queryClient = useQueryClient();
const iotaClient = useIotaClient();
-
+ const router = useRouter();
+ const [isMigrationDialogOpen, setIsMigrationDialogOpen] = useState(false);
const [selectedStardustObjectsCategory, setSelectedStardustObjectsCategory] = useState<
StardustOutputMigrationStatus | undefined
>(undefined);
@@ -43,8 +43,8 @@ function MigrationDashboardPage(): JSX.Element {
const {
migratableBasicOutputs,
migratableNftOutputs,
- unmigratableBasicOutputs,
- unmigratableNftOutputs,
+ timelockedBasicOutputs,
+ timelockedNftOutputs,
} = stardustMigrationObjects || {};
const {
@@ -56,9 +56,9 @@ function MigrationDashboardPage(): JSX.Element {
nftOutputs: migratableNftOutputs,
address,
});
- const { totalUnmigratableObjects } = summarizeUnmigratableObjectValues({
- basicOutputs: unmigratableBasicOutputs,
- nftOutputs: unmigratableNftOutputs,
+ const { totalTimelockedObjects } = summarizeTimelockedObjectValues({
+ basicOutputs: timelockedBasicOutputs,
+ nftOutputs: timelockedNftOutputs,
});
const hasMigratableObjects =
@@ -108,7 +108,7 @@ function MigrationDashboardPage(): JSX.Element {
const TIMELOCKED_ASSETS_CARDS: MigrationDisplayCardProps[] = [
{
- title: `${totalUnmigratableObjects}`,
+ title: `${totalTimelockedObjects}`,
subtitle: 'Time-locked',
icon: Clock,
},
@@ -125,29 +125,27 @@ function MigrationDashboardPage(): JSX.Element {
selectedStardustObjectsCategory === StardustOutputMigrationStatus.TimeLocked
) {
return [
- ...stardustMigrationObjects.unmigratableBasicOutputs,
- ...stardustMigrationObjects.unmigratableNftOutputs,
+ ...stardustMigrationObjects.timelockedBasicOutputs,
+ ...stardustMigrationObjects.timelockedNftOutputs,
];
}
}
return [];
}, [selectedStardustObjectsCategory, stardustMigrationObjects]);
- function openMigratePopup(): void {
- openPopup(
-
,
- );
+ function openMigrationDialog(): void {
+ setIsMigrationDialogOpen(true);
}
function handleCloseDetailsPanel() {
setSelectedStardustObjectsCategory(undefined);
}
+ function handleMigrationDialogClose() {
+ setIsMigrationDialogOpen(false);
+ router.push('/');
+ }
+
return (
+ {isMigrationDialogOpen && (
+
+ )}
}
@@ -212,7 +224,7 @@ function MigrationDashboardPage(): JSX.Element {
disabled={
selectedStardustObjectsCategory ===
StardustOutputMigrationStatus.TimeLocked ||
- !totalUnmigratableObjects
+ !totalTimelockedObjects
}
onClick={() =>
setSelectedStardustObjectsCategory(
diff --git a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx
index 2b95cf643b9..e29d94a7fef 100644
--- a/apps/wallet-dashboard/app/(protected)/vesting/page.tsx
+++ b/apps/wallet-dashboard/app/(protected)/vesting/page.tsx
@@ -13,17 +13,8 @@ import {
} from '@/components';
import { UnstakeDialogView } from '@/components/Dialogs/unstake/enums';
import { useUnstakeDialog } from '@/components/Dialogs/unstake/hooks';
-import { useGetCurrentEpochStartTimestamp, useNotifications } from '@/hooks';
-import {
- buildSupplyIncreaseVestingSchedule,
- formatDelegatedTimelockedStake,
- getLatestOrEarliestSupplyIncreaseVestingPayout,
- getVestingOverview,
- groupTimelockedStakedObjects,
- isTimelockedUnlockable,
- mapTimelockObjects,
- TimelockedStakedObjectsGrouped,
-} from '@/lib/utils';
+import { useGetSupplyIncreaseVestingObjects, useNotifications } from '@/hooks';
+import { groupTimelockedStakedObjects, TimelockedStakedObjectsGrouped } from '@/lib/utils';
import { NotificationType } from '@/stores/notificationStore';
import { useFeature } from '@growthbook/growthbook-react';
import {
@@ -46,13 +37,9 @@ import {
} from '@iota/apps-ui-kit';
import {
Theme,
- TIMELOCK_IOTA_TYPE,
useFormatCoin,
useGetActiveValidatorsInfo,
- useGetAllOwnedObjects,
- useGetTimelockedStakedObjects,
useTheme,
- useUnlockTimelockedObjectsTransaction,
useCountdownByTimestamp,
Feature,
} from '@iota/core';
@@ -74,24 +61,13 @@ export default function VestingDashboardPage(): JSX.Element {
const [timelockedObjectsToUnstake, setTimelockedObjectsToUnstake] =
useState(null);
const account = useCurrentAccount();
+ const address = account?.address || '';
const iotaClient = useIotaClient();
const router = useRouter();
const { data: system } = useIotaClientQuery('getLatestIotaSystemState');
const [isVestingScheduleDialogOpen, setIsVestingScheduleDialogOpen] = useState(false);
const { addNotification } = useNotifications();
- const { data: currentEpochMs } = useGetCurrentEpochStartTimestamp();
const { data: activeValidators } = useGetActiveValidatorsInfo();
- const { data: timelockedObjects, refetch: refetchGetAllOwnedObjects } = useGetAllOwnedObjects(
- account?.address || '',
- {
- StructType: TIMELOCK_IOTA_TYPE,
- },
- );
- const {
- data: timelockedStakedObjects,
- isLoading: istimelockedStakedObjectsLoading,
- refetch: refetchTimelockedStakedObjects,
- } = useGetTimelockedStakedObjects(account?.address || '');
const { mutateAsync: signAndExecuteTransaction } = useSignAndExecuteTransaction();
const { theme } = useTheme();
@@ -102,16 +78,19 @@ export default function VestingDashboardPage(): JSX.Element {
const supplyIncreaseVestingEnabled = useFeature(Feature.SupplyIncreaseVesting).value;
- const timelockedMapped = mapTimelockObjects(timelockedObjects || []);
- const timelockedstakedMapped = formatDelegatedTimelockedStake(timelockedStakedObjects || []);
+ const {
+ nextPayout,
+ supplyIncreaseVestingPortfolio,
+ supplyIncreaseVestingSchedule,
+ supplyIncreaseVestingMapped,
+ supplyIncreaseVestingStakedMapped,
+ isTimelockedStakedObjectsLoading,
+ unlockAllSupplyIncreaseVesting,
+ refreshStakeList,
+ } = useGetSupplyIncreaseVestingObjects(address);
const timelockedStakedObjectsGrouped: TimelockedStakedObjectsGrouped[] =
- groupTimelockedStakedObjects(timelockedstakedMapped || []);
-
- const vestingSchedule = getVestingOverview(
- [...timelockedMapped, ...timelockedstakedMapped],
- Number(currentEpochMs),
- );
+ groupTimelockedStakedObjects(supplyIncreaseVestingStakedMapped || []);
const {
isDialogStakeOpen,
@@ -132,37 +111,22 @@ export default function VestingDashboardPage(): JSX.Element {
setView: setUnstakeDialogView,
} = useUnstakeDialog();
- const nextPayout = getLatestOrEarliestSupplyIncreaseVestingPayout(
- [...timelockedMapped, ...timelockedstakedMapped],
- Number(currentEpochMs),
- false,
- );
-
- const lastPayout = getLatestOrEarliestSupplyIncreaseVestingPayout(
- [...timelockedMapped, ...timelockedstakedMapped],
- Number(currentEpochMs),
- true,
- );
-
- const vestingPortfolio =
- lastPayout && buildSupplyIncreaseVestingSchedule(lastPayout, Number(currentEpochMs));
-
const formattedLastPayoutExpirationTime = useCountdownByTimestamp(
Number(nextPayout?.expirationTimestampMs),
);
const [formattedTotalVested, vestedSymbol] = useFormatCoin(
- vestingSchedule.totalVested,
+ supplyIncreaseVestingSchedule.totalVested,
IOTA_TYPE_ARG,
);
const [formattedTotalLocked, lockedSymbol] = useFormatCoin(
- vestingSchedule.totalLocked,
+ supplyIncreaseVestingSchedule.totalLocked,
IOTA_TYPE_ARG,
);
const [formattedAvailableClaiming, availableClaimingSymbol] = useFormatCoin(
- vestingSchedule.availableClaiming,
+ supplyIncreaseVestingSchedule.availableClaiming,
IOTA_TYPE_ARG,
);
@@ -178,30 +142,15 @@ export default function VestingDashboardPage(): JSX.Element {
}
const [totalStakedFormatted, totalStakedSymbol] = useFormatCoin(
- vestingSchedule.totalStaked,
+ supplyIncreaseVestingSchedule.totalStaked,
IOTA_TYPE_ARG,
);
const [totalEarnedFormatted, totalEarnedSymbol] = useFormatCoin(
- vestingSchedule.totalEarned,
+ supplyIncreaseVestingSchedule.totalEarned,
IOTA_TYPE_ARG,
);
- const unlockedTimelockedObjects = timelockedMapped?.filter((timelockedObject) =>
- isTimelockedUnlockable(timelockedObject, Number(currentEpochMs)),
- );
- const unlockedTimelockedObjectIds: string[] =
- unlockedTimelockedObjects.map((timelocked) => timelocked.id.id) || [];
- const { data: unlockAllTimelockedObjects } = useUnlockTimelockedObjectsTransaction(
- account?.address || '',
- unlockedTimelockedObjectIds,
- );
-
- function refreshStakeList() {
- refetchTimelockedStakedObjects();
- refetchGetAllOwnedObjects();
- }
-
function handleOnSuccess(digest: string): void {
setTimelockedObjectsToUnstake(null);
@@ -213,13 +162,13 @@ export default function VestingDashboardPage(): JSX.Element {
}
const handleCollect = () => {
- if (!unlockAllTimelockedObjects?.transactionBlock) {
+ if (!unlockAllSupplyIncreaseVesting?.transactionBlock) {
addNotification('Failed to create a Transaction', NotificationType.Error);
return;
}
signAndExecuteTransaction(
{
- transaction: unlockAllTimelockedObjects.transactionBlock,
+ transaction: unlockAllSupplyIncreaseVesting.transactionBlock,
},
{
onSuccess: (tx) => {
@@ -240,7 +189,7 @@ export default function VestingDashboardPage(): JSX.Element {
openUnstakeDialog(UnstakeDialogView.TimelockedUnstake);
}
- function openReceiveTokenPopup(): void {
+ function openReceiveTokenDialog(): void {
setIsVestingScheduleDialogOpen(true);
}
@@ -258,7 +207,7 @@ export default function VestingDashboardPage(): JSX.Element {
}
}, [router, supplyIncreaseVestingEnabled]);
- if (istimelockedStakedObjectsLoading) {
+ if (isTimelockedStakedObjectsLoading) {
return (
@@ -304,8 +253,8 @@ export default function VestingDashboardPage(): JSX.Element {
title="Collect"
buttonType={ButtonType.Primary}
buttonDisabled={
- !vestingSchedule.availableClaiming ||
- vestingSchedule.availableClaiming === 0n
+ !supplyIncreaseVestingSchedule.availableClaiming ||
+ supplyIncreaseVestingSchedule.availableClaiming === 0n
}
/>
@@ -326,23 +275,23 @@ export default function VestingDashboardPage(): JSX.Element {
/>
- {vestingPortfolio && (
+ {supplyIncreaseVestingPortfolio && (
)}
- {timelockedstakedMapped.length === 0 ? (
+ {supplyIncreaseVestingMapped.length === 0 ? (
- {timelockedstakedMapped.length !== 0 ? (
+ {supplyIncreaseVestingMapped.length !== 0 ? (
{
setStakeDialogView(StakeDialogView.SelectValidator);
}}
@@ -422,8 +373,9 @@ export default function VestingDashboardPage(): JSX.Element {
setView={setStakeDialogView}
selectedValidator={selectedValidator}
setSelectedValidator={setSelectedValidator}
- maxStakableTimelockedAmount={BigInt(vestingSchedule.availableStaking)}
- onUnstakeClick={openUnstakeDialog}
+ maxStakableTimelockedAmount={BigInt(
+ supplyIncreaseVestingSchedule.availableStaking,
+ )}
/>
)}
diff --git a/apps/wallet-dashboard/app/globals.css b/apps/wallet-dashboard/app/globals.css
index 04c6811f389..69ca23f41f2 100644
--- a/apps/wallet-dashboard/app/globals.css
+++ b/apps/wallet-dashboard/app/globals.css
@@ -24,7 +24,6 @@ body {
'balance'
'staking'
'coins'
- 'vesting'
'activity';
&
@@ -36,13 +35,29 @@ body {
height: 200px;
}
}
- .home-page-grid-container:has(.with-migration) {
+ .home-page-grid-container:has(.with-vesting):not(:has(.with-migration)) {
+ grid-template-areas:
+ 'balance'
+ 'staking'
+ 'vesting'
+ 'coins'
+ 'activity';
+ }
+ .home-page-grid-container:has(.with-migration):not(:has(.with-vesting)) {
grid-template-areas:
'balance'
'staking'
'migration'
'coins'
+ 'activity';
+ }
+ .home-page-grid-container:has(.with-migration):has(.with-vesting) {
+ grid-template-areas:
+ 'balance'
+ 'staking'
+ 'migration'
'vesting'
+ 'coins'
'activity';
}
@@ -53,28 +68,56 @@ body {
'balance balance'
'staking staking'
'coins coins'
+ 'activity activity';
+ }
+ .home-page-grid-container:has(.with-vesting):not(:has(.with-migration)) {
+ grid-template-areas:
+ 'balance balance'
+ 'staking staking'
'vesting vesting'
+ 'coins coins'
'activity activity';
}
- .home-page-grid-container:has(.with-migration) {
+ .home-page-grid-container:has(.with-migration):not(:has(.with-vesting)) {
grid-template-areas:
'balance balance'
'staking migration'
'coins coins'
+ 'activity activity';
+ }
+ .home-page-grid-container:has(.with-migration):has(.with-vesting) {
+ grid-template-areas:
+ 'balance balance'
+ 'staking migration'
'vesting vesting'
+ 'coins coins'
'activity activity';
}
}
@screen md {
.home-page-grid-container {
+ min-height: 700px;
+ height: calc(100vh - 140px);
@apply grid-cols-3;
+ grid-template-areas:
+ 'balance staking staking'
+ 'coins activity activity';
+ }
+ .home-page-grid-container:has(.with-vesting):not(:has(.with-migration)) {
grid-template-areas:
'balance staking staking'
'coins vesting vesting'
'coins activity activity';
}
- .home-page-grid-container:has(.with-migration) {
+
+ .home-page-grid-container:has(.with-migration):not(:has(.with-vesting)) {
+ grid-template-areas:
+ 'balance staking migration'
+ 'coins activity activity';
+ }
+
+ .home-page-grid-container:has(.with-migration):has(.with-vesting) {
grid-template-areas:
'balance staking migration'
'coins vesting vesting'
diff --git a/apps/wallet-dashboard/app/page.tsx b/apps/wallet-dashboard/app/page.tsx
index e3036bf38c2..3392c231d31 100644
--- a/apps/wallet-dashboard/app/page.tsx
+++ b/apps/wallet-dashboard/app/page.tsx
@@ -63,8 +63,10 @@ function HomeDashboardPage(): JSX.Element {
-
+
© IOTA Foundation {CURRENT_YEAR}
+
+ {process.env.NEXT_PUBLIC_DASHBOARD_REV}
>
diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx
index ec3d8d38d11..c71390a33aa 100644
--- a/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/Assets/AssetDialog.tsx
@@ -4,17 +4,20 @@
import React, { useState } from 'react';
import { Dialog } from '@iota/apps-ui-kit';
import { FormikProvider, useFormik } from 'formik';
-import { useCurrentAccount } from '@iota/dapp-kit';
+import { useIotaClient, useCurrentAccount } from '@iota/dapp-kit';
import { createNftSendValidationSchema } from '@iota/core';
import { DetailsView, SendView } from './views';
import { IotaObjectData } from '@iota/iota-sdk/client';
import { AssetsDialogView } from './constants';
import { useCreateSendAssetTransaction, useNotifications } from '@/hooks';
import { NotificationType } from '@/stores/notificationStore';
+import { TransactionDetailsView } from '../SendToken';
+import { DialogLayout } from '../layout';
interface AssetsDialogProps {
onClose: () => void;
asset: IotaObjectData;
+ refetchAssets: () => void;
}
interface FormValues {
@@ -25,12 +28,14 @@ const INITIAL_VALUES: FormValues = {
to: '',
};
-export function AssetDialog({ onClose, asset }: AssetsDialogProps): JSX.Element {
+export function AssetDialog({ onClose, asset, refetchAssets }: AssetsDialogProps): JSX.Element {
const [view, setView] = useState
(AssetsDialogView.Details);
const account = useCurrentAccount();
+ const [digest, setDigest] = useState('');
const activeAddress = account?.address ?? '';
const objectId = asset?.objectId ?? '';
const { addNotification } = useNotifications();
+ const iotaClient = useIotaClient();
const validationSchema = createNftSendValidationSchema(activeAddress, objectId);
const { mutation: sendAsset } = useCreateSendAssetTransaction(objectId);
@@ -44,10 +49,16 @@ export function AssetDialog({ onClose, asset }: AssetsDialogProps): JSX.Element
async function onSubmit(values: FormValues) {
try {
- await sendAsset.mutateAsync(values.to);
+ const executed = await sendAsset.mutateAsync(values.to);
+
+ const tx = await iotaClient.waitForTransaction({
+ digest: executed.digest,
+ });
+
+ setDigest(tx.digest);
+ refetchAssets();
addNotification('Transfer transaction successful', NotificationType.Success);
- onClose();
- setView(AssetsDialogView.Details);
+ setView(AssetsDialogView.TransactionDetails);
} catch {
addNotification('Transfer transaction failed', NotificationType.Error);
}
@@ -66,16 +77,26 @@ export function AssetDialog({ onClose, asset }: AssetsDialogProps): JSX.Element
}
return (
);
}
diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts b/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts
index 88cb34c15b1..242da33c2c3 100644
--- a/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts
+++ b/apps/wallet-dashboard/components/Dialogs/Assets/constants/AssetsDialogView.ts
@@ -4,4 +4,5 @@
export enum AssetsDialogView {
Details = 'Details',
Send = 'Send',
+ TransactionDetails = 'TransactionDetails',
}
diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx
index 3929ba0062f..8520d62a484 100644
--- a/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/Assets/views/DetailsView.tsx
@@ -13,7 +13,7 @@ import {
} from '@iota/apps-ui-kit';
import Link from 'next/link';
import { formatAddress } from '@iota/iota-sdk/utils';
-import { DialogLayout, DialogLayoutBody, DialogLayoutFooter } from '../../layout';
+import { DialogLayoutBody, DialogLayoutFooter } from '../../layout';
import { IotaObjectData } from '@iota/iota-sdk/client';
import { ExplorerLink } from '@/components/ExplorerLink';
import { useCurrentAccount } from '@iota/dapp-kit';
@@ -55,7 +55,7 @@ export function DetailsView({ onClose, asset, onSend }: DetailsViewProps) {
}
return (
-
+ <>
@@ -195,6 +195,6 @@ export function DetailsView({ onClose, asset, onSend }: DetailsViewProps) {
)}
-
+ >
);
}
diff --git a/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx b/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx
index b5757582c7b..3d0350478ac 100644
--- a/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/Assets/views/SendView.tsx
@@ -4,7 +4,7 @@
import React from 'react';
import { AddressInput, useNftDetails } from '@iota/core';
import { useFormikContext } from 'formik';
-import { DialogLayout, DialogLayoutFooter, DialogLayoutBody } from '../../layout';
+import { DialogLayoutFooter, DialogLayoutBody } from '../../layout';
import {
Button,
ButtonHtmlType,
@@ -33,7 +33,7 @@ export function SendView({ asset, onClose, onBack }: SendViewProps) {
const { nftName, nftImageUrl } = useNftDetails(objectId, senderAddress);
return (
-
+ <>
@@ -65,6 +65,6 @@ export function SendView({ asset, onClose, onBack }: SendViewProps) {
onClick={submitForm}
/>
-
+ >
);
}
diff --git a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx
index 913e362e27d..a33f018a09c 100644
--- a/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx
+++ b/apps/wallet-dashboard/components/Dialogs/SendToken/SendTokenDialog.tsx
@@ -13,7 +13,7 @@ import { INITIAL_VALUES } from './constants';
import { IOTA_TYPE_ARG } from '@iota/iota-sdk/utils';
import { useTransferTransactionMutation } from '@/hooks';
-interface SendCoinPopupProps {
+interface SendCoinDialogProps {
coin: CoinBalance;
activeAddress: string;
setOpen: (bool: boolean) => void;
@@ -30,7 +30,7 @@ function SendTokenDialogBody({
coin,
activeAddress,
setOpen,
-}: SendCoinPopupProps): React.JSX.Element {
+}: SendCoinDialogProps): React.JSX.Element {
const [step, setStep] = useState
(FormStep.EnterValues);
const [selectedCoin, setSelectedCoin] = useState(coin);
const [formData, setFormData] = useState(INITIAL_VALUES);
@@ -125,7 +125,7 @@ function SendTokenDialogBody({
);
}
-export function SendTokenDialog(props: SendCoinPopupProps) {
+export function SendTokenDialog(props: SendCoinDialogProps) {
return (