diff --git a/packages/query/src/block-processor.ts b/packages/query/src/block-processor.ts index 5d4a1a0853..955b9c7c44 100644 --- a/packages/query/src/block-processor.ts +++ b/packages/query/src/block-processor.ts @@ -1,7 +1,7 @@ import { RootQuerier } from './root-querier'; import { sha256Hash } from '@penumbra-zone/crypto-web'; -import { computePositionId, decodeSctRoot } from '@penumbra-zone/wasm'; +import { computePositionId, decodeSctRoot, getLpNftMetadata } from '@penumbra-zone/wasm'; import { PositionState, PositionState_PositionStateEnum, @@ -296,19 +296,17 @@ export class BlockProcessor implements BlockProcessorInterface { } private async identifyLpNftPositions(txs: Transaction[]) { - const positionStates = [ - PositionState_PositionStateEnum.OPENED, - PositionState_PositionStateEnum.CLOSED, - PositionState_PositionStateEnum.WITHDRAWN, - PositionState_PositionStateEnum.CLAIMED, + const positionStates: PositionState[] = [ + new PositionState({ state: PositionState_PositionStateEnum.OPENED }), + new PositionState({ state: PositionState_PositionStateEnum.CLOSED }), + new PositionState({ state: PositionState_PositionStateEnum.WITHDRAWN, sequence: 0n }), ]; for (const tx of txs) { for (const { action } of tx.body?.actions ?? []) { if (action.case === 'positionOpen' && action.value.position) { for (const state of positionStates) { - const positionState = new PositionState({ state }); - const metadata = this.viewServer.getLpNftMetadata(action.value.position, positionState); + const metadata = getLpNftMetadata(computePositionId(action.value.position), state); await this.indexedDb.saveAssetsMetadata(metadata); } // to optimize on-chain storage PositionId is not written in the positionOpen action, @@ -325,16 +323,15 @@ export class BlockProcessor implements BlockProcessorInterface { ); } if (action.case === 'positionWithdraw' && action.value.positionId) { - await this.indexedDb.updatePosition( - action.value.positionId, - new PositionState({ state: PositionState_PositionStateEnum.WITHDRAWN }), - ); - } - if (action.case === 'positionRewardClaim' && action.value.positionId) { - await this.indexedDb.updatePosition( - action.value.positionId, - new PositionState({ state: PositionState_PositionStateEnum.CLAIMED }), - ); + // Record the LPNFT for the current sequence number. + const positionState = new PositionState({ + state: PositionState_PositionStateEnum.WITHDRAWN, + sequence: action.value.sequence, + }); + const metadata = getLpNftMetadata(action.value.positionId, positionState); + await this.indexedDb.saveAssetsMetadata(metadata); + + await this.indexedDb.updatePosition(action.value.positionId, positionState); } } } diff --git a/packages/types/src/servers.ts b/packages/types/src/servers.ts index b1494b649a..be209d9d5b 100644 --- a/packages/types/src/servers.ts +++ b/packages/types/src/servers.ts @@ -1,11 +1,6 @@ import { ScanBlockResult } from './state-commitment-tree'; import { CompactBlock } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/compact_block/v1/compact_block_pb'; import { MerkleRoot } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/crypto/tct/v1/tct_pb'; -import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb'; -import { - Position, - PositionState, -} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/dex/v1/dex_pb'; export interface ViewServerInterface { fullViewingKey: string; @@ -13,5 +8,4 @@ export interface ViewServerInterface { flushUpdates(): ScanBlockResult; resetTreeToStored(): Promise; getSctRoot(): MerkleRoot; - getLpNftMetadata(position: Position, positionState: PositionState): Metadata; } diff --git a/packages/wasm/crate/src/dex.rs b/packages/wasm/crate/src/dex.rs index 5f5b0a0d04..fa806fbdaf 100644 --- a/packages/wasm/crate/src/dex.rs +++ b/packages/wasm/crate/src/dex.rs @@ -1,5 +1,6 @@ use crate::utils; -use penumbra_dex::lp::position::Position; +use penumbra_dex::lp::position::{Id, Position}; +use penumbra_dex::lp::LpNft; use serde_wasm_bindgen::Error; use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsValue; @@ -15,3 +16,21 @@ pub fn compute_position_id(position: JsValue) -> Result { let position: Position = serde_wasm_bindgen::from_value(position)?; serde_wasm_bindgen::to_value(&position.id()) } + +/// get LP NFT asset +/// Arguments: +/// position_value: `lp::position::Position` +/// position_state_value: `lp::position::State` +/// Returns: `DenomMetadata` +#[wasm_bindgen] +pub fn get_lpnft_asset( + position_id_value: JsValue, + position_state_value: JsValue, +) -> Result { + utils::set_panic_hook(); + let position_id: Id = serde_wasm_bindgen::from_value(position_id_value)?; + let position_state = serde_wasm_bindgen::from_value(position_state_value)?; + let lp_nft = LpNft::new(position_id, position_state); + let denom = lp_nft.denom(); + serde_wasm_bindgen::to_value(&denom) +} diff --git a/packages/wasm/crate/src/view_server.rs b/packages/wasm/crate/src/view_server.rs index 8a02bf8fc0..b14762384d 100644 --- a/packages/wasm/crate/src/view_server.rs +++ b/packages/wasm/crate/src/view_server.rs @@ -1,23 +1,20 @@ use std::convert::TryInto; use std::{collections::BTreeMap, str::FromStr}; -use serde::{Deserialize, Serialize}; -use serde_wasm_bindgen::Error; -use serde_wasm_bindgen::Serializer; -use wasm_bindgen::prelude::wasm_bindgen; -use wasm_bindgen::JsValue; - use penumbra_asset::asset::{Id, Metadata}; use penumbra_compact_block::{CompactBlock, StatePayload}; -use penumbra_dex::lp::position::Position; -use penumbra_dex::lp::LpNft; use penumbra_keys::FullViewingKey; use penumbra_sct::Nullifier; use penumbra_shielded_pool::note; use penumbra_tct as tct; use penumbra_tct::Witness::*; +use serde::{Deserialize, Serialize}; +use serde_wasm_bindgen::Error; +use serde_wasm_bindgen::Serializer; use tct::storage::{StoreCommitment, StoreHash, StoredPosition, Updates}; use tct::{Forgotten, Tree}; +use wasm_bindgen::prelude::wasm_bindgen; +use wasm_bindgen::JsValue; use crate::error::WasmResult; use crate::note_record::SpendableNoteRecord; @@ -304,26 +301,6 @@ impl ViewServer { let root = self.sct.root(); serde_wasm_bindgen::to_value(&root) } - - /// get LP NFT asset - /// Arguments: - /// position_value: `lp::position::Position` - /// position_state_value: `lp::position::State` - /// Returns: `DenomMetadata` - #[wasm_bindgen] - pub fn get_lpnft_asset( - &mut self, - position_value: JsValue, - position_state_value: JsValue, - ) -> Result { - utils::set_panic_hook(); - - let position: Position = serde_wasm_bindgen::from_value(position_value)?; - let position_state = serde_wasm_bindgen::from_value(position_state_value)?; - let lp_nft = LpNft::new(position.id(), position_state); - let denom = lp_nft.denom(); - serde_wasm_bindgen::to_value(&denom) - } } pub fn load_tree(stored_tree: StoredTree) -> Tree { diff --git a/packages/wasm/src/dex.ts b/packages/wasm/src/dex.ts index 8ad90cf97d..2430295ae9 100644 --- a/packages/wasm/src/dex.ts +++ b/packages/wasm/src/dex.ts @@ -1,10 +1,21 @@ -import { compute_position_id } from '../wasm'; +import { compute_position_id, get_lpnft_asset } from '../wasm'; import { Position, PositionId, + PositionState, } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/dex/v1/dex_pb'; +import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb'; +import { JsonValue } from '@bufbuild/protobuf'; export const computePositionId = (position: Position): PositionId => { const result = compute_position_id(position.toJson()) as unknown; return PositionId.fromJsonString(JSON.stringify(result)); }; + +export const getLpNftMetadata = ( + positionId: PositionId, + positionState: PositionState, +): Metadata => { + const result = get_lpnft_asset(positionId.toJson(), positionState.toJson()) as JsonValue; + return Metadata.fromJson(result); +}; diff --git a/packages/wasm/src/view-server.ts b/packages/wasm/src/view-server.ts index 42a19f1a5e..e56f4be4c4 100644 --- a/packages/wasm/src/view-server.ts +++ b/packages/wasm/src/view-server.ts @@ -1,11 +1,6 @@ import { ViewServer as WasmViewServer } from '../wasm'; import { CompactBlock } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/compact_block/v1/compact_block_pb'; import { MerkleRoot } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/crypto/tct/v1/tct_pb'; -import { Metadata } from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/asset/v1/asset_pb'; -import { - Position, - PositionState, -} from '@buf/penumbra-zone_penumbra.bufbuild_es/penumbra/core/component/dex/v1/dex_pb'; import { JsonObject, JsonValue } from '@bufbuild/protobuf'; import { SpendableNoteRecord, @@ -96,12 +91,4 @@ export class ViewServer implements ViewServerInterface { newSwaps: wasmJson.new_swaps.map(s => SwapRecord.fromJsonString(s)), }; } - - getLpNftMetadata(position: Position, positionState: PositionState): Metadata { - const result = this.wasmViewServer.get_lpnft_asset( - position.toJson(), - positionState.toJson(), - ) as JsonValue; - return Metadata.fromJsonString(JSON.stringify(result)); - } }