Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion biome.jsonc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
"$schema": "https://biomejs.dev/schemas/2.5.1/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
8 changes: 4 additions & 4 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/apps/assembly/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @eveworld/assembly

## 0.3.4

### Patch Changes

- apply fuel optimistic update, bump wallet-core version

## 0.3.3

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/apps/assembly/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@eveworld/assembly",
"private": true,
"version": "0.3.3",
"version": "0.3.4",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
6 changes: 0 additions & 6 deletions packages/libs/dapp-kit/CHANGELOG.md
Comment thread
ccp-bofai marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
# @evefrontier/dapp-kit

## 0.1.11

### Patch Changes

- use optimistic updates for inventory

## 0.1.10

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/libs/dapp-kit/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@evefrontier/dapp-kit",
"version": "0.1.11",
Comment thread
fcsondheim marked this conversation as resolved.
"version": "0.1.10",
"description": "React SDK for EVE Frontier dApps on Sui",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
Expand Down Expand Up @@ -41,7 +41,7 @@
}
},
"dependencies": {
"@evefrontier/wallet-core": "0.0.3",
"@evefrontier/wallet-core": "0.0.4",
"@mysten/dapp-kit-core": "^1.2.2",
"@mysten/dapp-kit-react": "^2.0.1",
"@mysten/sui": "^2.14.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/libs/dapp-kit/utils/__tests__/constants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ describe('constants', () => {
],
[
TenantId.STILLNESS,
'0x2a66a89b5a735738ffa4423ac024d23571326163f324f9051557617319e59d60::EVE::EVE',
'0xac361aa5ceb726bd974f885c9dea9e55dc9bc98fa1f5731c5965a810707bf0b8::EVE::EVE',
],
])('returns the EVE coin type for tenant %s', (tenantId, expected) => {
expect(getEveCoinType(tenantId)).toBe(expected)
Expand Down
60 changes: 60 additions & 0 deletions packages/libs/dapp-kit/utils/__tests__/fuelEventBcs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { describe, expect, it } from 'vitest'

import {
decodeFuelEventBcs,
fuelEventBcsToParsedJson,
} from '../events/fuelEventBcs'

function hexToBytes(hex: string): Uint8Array {
const bytes = new Uint8Array(hex.length / 2)
for (let index = 0; index < bytes.length; index += 1) {
bytes[index] = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16)
}
return bytes
}

// Manually constructed FuelEvent BCS bytes matching the on-chain Move struct:
// assembly_id: 0x34d08b4e...cc951b (32 bytes)
// assembly_key: { item_id: 1 (u64 LE), tenant: "stillness" }
// type_id: 77810, old_quantity: 10, new_quantity: 5
// is_burning: false, action: WITHDRAWN (variant index 1)
const FUEL_EVENT_BCS_HEX =
'34d08b4e1afe6a4babcc0642d6a676160df6b777b49214d5c964b4e874cc951b' +
'0100000000000000' +
'09' +
'7374696c6c6e657373' +
'f22f010000000000' +
'0a00000000000000' +
'0500000000000000' +
'00' +
'01'

describe('fuelEventBcs', () => {
it('decodes a FuelEvent from BCS bytes', () => {
const decoded = decodeFuelEventBcs(hexToBytes(FUEL_EVENT_BCS_HEX))

expect(fuelEventBcsToParsedJson(decoded)).toMatchObject({
assembly_id:
'0x34d08b4e1afe6a4babcc0642d6a676160df6b777b49214d5c964b4e874cc951b',
assembly_key: {
item_id: '1',
tenant: 'stillness',
},
type_id: '77810',
old_quantity: '10',
new_quantity: '5',
is_burning: false,
})
})

it('decodes the action variant kind', () => {
const decoded = decodeFuelEventBcs(hexToBytes(FUEL_EVENT_BCS_HEX))
const json = fuelEventBcsToParsedJson(decoded)
// bcs.enum returns a discriminated union: { $kind: '<Variant>', <Variant>: true }
expect((json.action as Record<string, unknown>)?.$kind).toBe('WITHDRAWN')
})

it('throws on malformed BCS bytes', () => {
expect(() => decodeFuelEventBcs(new Uint8Array([0x00, 0x01]))).toThrow()
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { describe, expect, it } from 'vitest'
import {
decodeInventoryEventBcs,
inventoryEventBcsToParsedJson,
} from '../inventoryEventBcs'
} from '../events/inventoryEventBcs'

function hexToBytes(hex: string): Uint8Array {
const bytes = new Uint8Array(hex.length / 2)
Expand Down
49 changes: 49 additions & 0 deletions packages/libs/dapp-kit/utils/events/__tests__/eventRefresh.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
extractInventoryEventsFromCheckpoint,
} from '../checkpointStream'
import { createEventRefetchScheduler } from '../eventRefresh'
import { getFuelEventType } from '../fuelEventHandlers'
import {
applyInventoryEventToAssembly,
getInventoryEventTarget,
Expand Down Expand Up @@ -1148,4 +1149,52 @@ describe('event refresh helpers', () => {
},
])
})

it('extracts fuel events from gRPC BCS bytes when json is absent', () => {
// Manually constructed FuelEvent BCS: assembly_id 0x34d0...951b,
// assembly_key { item_id: 1, tenant: "stillness" }, type_id: 77810,
// old_quantity: 10, new_quantity: 5, is_burning: false, action: WITHDRAWN
const FUEL_EVENT_BCS_HEX =
'34d08b4e1afe6a4babcc0642d6a676160df6b777b49214d5c964b4e874cc951b' +
'0100000000000000' +
'09' +
'7374696c6c6e657373' +
'f22f010000000000' +
'0a00000000000000' +
'0500000000000000' +
'00' +
'01'

const events = extractInventoryEventsFromCheckpoint(
{
transactions: [
{
digest: 'abc123',
events: {
events: [
{
eventType: getFuelEventType(PACKAGE_ID),
contents: {
value: hexToBytes(FUEL_EVENT_BCS_HEX),
},
},
],
},
},
],
},
[getFuelEventType(PACKAGE_ID)],
)

expect(events).toHaveLength(1)
expect(events[0].type).toBe(getFuelEventType(PACKAGE_ID))
expect(events[0].parsedJson).toMatchObject({
assembly_id: ASSEMBLY_OBJECT_ID,
assembly_key: { item_id: '1', tenant: 'stillness' },
type_id: '77810',
old_quantity: '10',
new_quantity: '5',
is_burning: false,
})
})
})
21 changes: 12 additions & 9 deletions packages/libs/dapp-kit/utils/events/checkpointStream.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { SuiEvent } from '@mysten/sui/jsonRpc'

import { createLogger } from '../logger'
import { isRecord } from '../utils'
import { decodeFuelEventBcs, fuelEventBcsToParsedJson } from './fuelEventBcs'
import {
decodeInventoryEventBcs,
inventoryEventBcsToParsedJson,
} from '../inventoryEventBcs'
import { createLogger } from '../logger'
import { isRecord } from '../utils'
} from './inventoryEventBcs'

const CHECKPOINT_STREAM_RECONNECT_MS = 1_000
// Rotate before the public fullnode ~30s stream cutoff.
Expand Down Expand Up @@ -105,17 +105,20 @@ function protobufStructToJson(
)
}

function parseInventoryEventPayloadFromStream(event: {
json?: ProtobufValue
contents?: { value?: Uint8Array }
}): Record<string, unknown> | null {
function parseEventPayloadFromStream(
event: { json?: ProtobufValue; contents?: { value?: Uint8Array } },
eventType: string,
): Record<string, unknown> | null {
const fromProtobuf = protobufValueToJson(event.json)
if (isRecord(fromProtobuf)) return fromProtobuf

const bcsBytes = event.contents?.value
if (!bcsBytes) return null

try {
if (eventType.endsWith('::fuel::FuelEvent')) {
return fuelEventBcsToParsedJson(decodeFuelEventBcs(bcsBytes))
}
return inventoryEventBcsToParsedJson(decodeInventoryEventBcs(bcsBytes))
Comment thread
fcsondheim marked this conversation as resolved.
} catch {
return null
Expand Down Expand Up @@ -326,7 +329,7 @@ export function extractInventoryEventsFromCheckpoint(
const type = getStreamEventType(event)
if (!eventTypes.includes(type)) return []

const parsedJson = parseInventoryEventPayloadFromStream(event)
const parsedJson = parseEventPayloadFromStream(event, type)
if (!parsedJson) return []

return [
Expand Down
12 changes: 12 additions & 0 deletions packages/libs/dapp-kit/utils/events/consts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { bcs } from '@mysten/sui/bcs'

export const BcsObjectId = bcs.fixedArray(32, bcs.u8()).transform({
input: (value: number[]) => value,
output: (value: number[]) =>
`0x${value.map((byte) => byte.toString(16).padStart(2, '0')).join('')}`,
})

export const TenantKey = bcs.struct('TenantKey', {
item_id: bcs.u64(),
tenant: bcs.string(),
})
64 changes: 64 additions & 0 deletions packages/libs/dapp-kit/utils/events/fuelEventBcs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { bcs } from '@mysten/sui/bcs'

import { BcsObjectId, TenantKey } from './consts'

const BcsAction = bcs.enum('Action', {
DEPOSITED: null,
WITHDRAWN: null,
BURNING_STARTED: null,
BURNING_STOPPED: null,
BURNING_UPDATED: null,
DELETED: null,
})

const FuelMoveEvent = bcs.struct('FuelEvent', {
assembly_id: BcsObjectId,
assembly_key: TenantKey,
type_id: bcs.u64(),
old_quantity: bcs.u64(),
new_quantity: bcs.u64(),
is_burning: bcs.bool(),
action: BcsAction,
})

// ----------------------------------------------------------------------------

export type DecodedFuelMoveEvent = {
assembly_id: string
assembly_key: { item_id: string; tenant: string }
type_id: string
old_quantity: string
new_quantity: string
is_burning: boolean
action: unknown
}

export function decodeFuelEventBcs(bytes: Uint8Array): DecodedFuelMoveEvent {
const decoded = FuelMoveEvent.parse(bytes)
return {
assembly_id: decoded.assembly_id,
assembly_key: {
item_id: String(decoded.assembly_key.item_id),
tenant: decoded.assembly_key.tenant,
},
type_id: String(decoded.type_id),
old_quantity: String(decoded.old_quantity),
new_quantity: String(decoded.new_quantity),
is_burning: Boolean(decoded.is_burning),
action: decoded.action,
}
}

export function fuelEventBcsToParsedJson(
decoded: DecodedFuelMoveEvent,
): Record<string, unknown> {
return {
assembly_id: decoded.assembly_id,
assembly_key: decoded.assembly_key,
type_id: decoded.type_id,
old_quantity: decoded.old_quantity,
new_quantity: decoded.new_quantity,
is_burning: decoded.is_burning,
action: decoded.action,
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import { bcs } from '@mysten/sui/bcs'

const BcsObjectId = bcs.fixedArray(32, bcs.u8()).transform({
input: (value: number[]) => value,
output: (value: number[]) =>
`0x${value.map((byte) => byte.toString(16).padStart(2, '0')).join('')}`,
})

const TenantKey = bcs.struct('TenantKey', {
item_id: bcs.u64(),
tenant: bcs.string(),
})
import { BcsObjectId, TenantKey } from './consts'

const InventoryMoveEvent = bcs.struct('InventoryMoveEvent', {
assembly_id: BcsObjectId,
Expand Down
13 changes: 7 additions & 6 deletions packages/libs/dapp-kit/utils/events/inventoryEventHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -252,12 +252,13 @@ export function applyInventoryEventToAssembly(
...assembly.storage,
mainInventory: {
...assembly.storage.mainInventory,
usedCapacity: adjustInventoryUsedCapacity(
assembly.storage.mainInventory.usedCapacity,
delta.quantity,
delta.typeId,
delta.operation,
),
usedCapacity:
adjustInventoryUsedCapacity(
assembly.storage.mainInventory.usedCapacity,
delta.quantity,
delta.typeId,
delta.operation,
) || '',
items: sortInventoryItemsByQuantity(
mergeInventoryItemsByTypeId(computeNextItems(items, delta)),
),
Expand Down
Loading
Loading