@shipload/sdk 1.0.0-next.2 → 1.0.0-next.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/shipload.d.ts +1709 -1044
- package/lib/shipload.js +6762 -4658
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +6653 -4614
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +833 -0
- package/lib/testing.js +3647 -0
- package/lib/testing.js.map +1 -0
- package/lib/testing.m.js +3641 -0
- package/lib/testing.m.js.map +1 -0
- package/package.json +15 -2
- package/src/capabilities/gathering.ts +17 -7
- package/src/capabilities/modules.ts +9 -0
- package/src/capabilities/storage.ts +1 -1
- package/src/contracts/platform.ts +211 -3
- package/src/contracts/server.ts +723 -438
- package/src/data/capabilities.ts +9 -329
- package/src/data/capability-formulas.ts +76 -0
- package/src/data/catalog.ts +0 -5
- package/src/data/colors.ts +14 -28
- package/src/data/entities.json +46 -10
- package/src/data/item-ids.ts +17 -13
- package/src/data/items.json +308 -37
- package/src/data/kind-registry.json +85 -0
- package/src/data/kind-registry.ts +150 -0
- package/src/data/metadata.ts +99 -24
- package/src/data/recipes-runtime.ts +3 -23
- package/src/data/recipes.json +265 -96
- package/src/derivation/build-methods.ts +45 -0
- package/src/derivation/capabilities.ts +414 -0
- package/src/derivation/capability-mappings.ts +117 -0
- package/src/derivation/crafting.ts +23 -24
- package/src/derivation/index.ts +8 -2
- package/src/derivation/reserve-regen.ts +34 -0
- package/src/derivation/resources.ts +125 -38
- package/src/derivation/stats.ts +1 -2
- package/src/derivation/stratum.ts +15 -19
- package/src/derivation/tiers.ts +28 -7
- package/src/entities/entity.ts +98 -0
- package/src/entities/gamestate.ts +3 -28
- package/src/entities/makers.ts +75 -129
- package/src/entities/slot-multiplier.ts +37 -0
- package/src/errors.ts +10 -15
- package/src/format.ts +26 -4
- package/src/index-module.ts +149 -40
- package/src/managers/actions.ts +184 -82
- package/src/managers/base.ts +2 -2
- package/src/managers/construction-types.ts +47 -0
- package/src/managers/construction.ts +147 -0
- package/src/managers/context.ts +9 -0
- package/src/managers/entities.ts +18 -66
- package/src/managers/epochs.ts +40 -0
- package/src/managers/index.ts +14 -1
- package/src/managers/locations.ts +2 -20
- package/src/managers/nft.ts +28 -0
- package/src/managers/plot.ts +123 -0
- package/src/nft/atomicassets.ts +231 -0
- package/src/nft/atomicdata.ts +130 -0
- package/src/nft/buildImmutableData.ts +319 -0
- package/src/nft/description.ts +45 -13
- package/src/nft/index.ts +3 -0
- package/src/resolution/describe-module.ts +5 -8
- package/src/resolution/display-name.ts +38 -10
- package/src/resolution/resolve-item.ts +20 -12
- package/src/scheduling/accessor.ts +4 -0
- package/src/scheduling/projection.ts +79 -27
- package/src/scheduling/schedule.ts +15 -1
- package/src/scheduling/task-cargo.ts +46 -0
- package/src/shipload.ts +5 -0
- package/src/subscriptions/manager.ts +40 -6
- package/src/subscriptions/mappers.ts +3 -8
- package/src/subscriptions/types.ts +3 -2
- package/src/testing/catalog-hash.ts +19 -0
- package/src/testing/index.ts +2 -0
- package/src/testing/projection-parity.ts +143 -0
- package/src/travel/travel.ts +61 -2
- package/src/types/index.ts +0 -1
- package/src/types.ts +17 -12
- package/src/utils/cargo.ts +27 -0
- package/src/utils/system.ts +25 -24
- package/src/entities/container.ts +0 -108
- package/src/entities/ship-deploy.ts +0 -258
- package/src/entities/ship.ts +0 -204
- package/src/entities/warehouse.ts +0 -119
- package/src/types/entity-traits.ts +0 -69
package/src/managers/entities.ts
CHANGED
|
@@ -1,99 +1,51 @@
|
|
|
1
1
|
import {Name, type NameType, type UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {BaseManager} from './base'
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {Container} from '../entities/container'
|
|
3
|
+
import {Entity} from '../entities/entity'
|
|
4
|
+
import type {EntityTypeName} from '../data/kind-registry'
|
|
6
5
|
import type {ServerContract} from '../contracts'
|
|
7
6
|
|
|
8
|
-
export type
|
|
7
|
+
export type {EntityTypeName} from '../data/kind-registry'
|
|
9
8
|
|
|
10
9
|
export class EntitiesManager extends BaseManager {
|
|
11
|
-
async getEntity(
|
|
10
|
+
async getEntity(id: UInt64Type): Promise<Entity> {
|
|
12
11
|
const result = await this.server.readonly('getentity', {
|
|
13
|
-
entity_type: Name.from(type),
|
|
14
12
|
entity_id: id,
|
|
15
13
|
})
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
return new Entity(result as ServerContract.Types.entity_info)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async getProjection(id: UInt64Type, taskCount?: number): Promise<unknown> {
|
|
18
|
+
return this.server.readonly('getprojstate', {
|
|
19
|
+
entity_id: id,
|
|
20
|
+
task_count: taskCount,
|
|
21
|
+
})
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
async getEntities(
|
|
21
25
|
owner: NameType | ServerContract.Types.player_row,
|
|
22
|
-
|
|
23
|
-
): Promise<
|
|
26
|
+
kind?: EntityTypeName
|
|
27
|
+
): Promise<Entity[]> {
|
|
24
28
|
const ownerName = this.resolveOwner(owner)
|
|
25
29
|
const result = await this.server.readonly('getentities', {
|
|
26
30
|
owner: ownerName,
|
|
27
|
-
entity_type:
|
|
31
|
+
entity_type: kind,
|
|
28
32
|
})
|
|
29
33
|
const entities = result as ServerContract.Types.entity_info[]
|
|
30
|
-
return entities.map((
|
|
34
|
+
return entities.map((e) => new Entity(e))
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
async getSummaries(
|
|
34
38
|
owner: NameType | ServerContract.Types.player_row,
|
|
35
|
-
|
|
39
|
+
kind?: EntityTypeName
|
|
36
40
|
): Promise<ServerContract.Types.entity_summary[]> {
|
|
37
41
|
const ownerName = this.resolveOwner(owner)
|
|
38
42
|
const result = await this.server.readonly('getsummaries', {
|
|
39
43
|
owner: ownerName,
|
|
40
|
-
entity_type:
|
|
44
|
+
entity_type: kind,
|
|
41
45
|
})
|
|
42
46
|
return result as ServerContract.Types.entity_summary[]
|
|
43
47
|
}
|
|
44
48
|
|
|
45
|
-
async getShip(id: UInt64Type): Promise<Ship> {
|
|
46
|
-
return (await this.getEntity('ship', id)) as Ship
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async getWarehouse(id: UInt64Type): Promise<Warehouse> {
|
|
50
|
-
return (await this.getEntity('warehouse', id)) as Warehouse
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async getContainer(id: UInt64Type): Promise<Container> {
|
|
54
|
-
return (await this.getEntity('container', id)) as Container
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async getShips(owner: NameType | ServerContract.Types.player_row): Promise<Ship[]> {
|
|
58
|
-
return (await this.getEntities(owner, 'ship')) as Ship[]
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async getWarehouses(owner: NameType | ServerContract.Types.player_row): Promise<Warehouse[]> {
|
|
62
|
-
return (await this.getEntities(owner, 'warehouse')) as Warehouse[]
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async getContainers(owner: NameType | ServerContract.Types.player_row): Promise<Container[]> {
|
|
66
|
-
return (await this.getEntities(owner, 'container')) as Container[]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
async getShipSummaries(
|
|
70
|
-
owner: NameType | ServerContract.Types.player_row
|
|
71
|
-
): Promise<ServerContract.Types.entity_summary[]> {
|
|
72
|
-
return this.getSummaries(owner, 'ship')
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async getWarehouseSummaries(
|
|
76
|
-
owner: NameType | ServerContract.Types.player_row
|
|
77
|
-
): Promise<ServerContract.Types.entity_summary[]> {
|
|
78
|
-
return this.getSummaries(owner, 'warehouse')
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
async getContainerSummaries(
|
|
82
|
-
owner: NameType | ServerContract.Types.player_row
|
|
83
|
-
): Promise<ServerContract.Types.entity_summary[]> {
|
|
84
|
-
return this.getSummaries(owner, 'container')
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
private wrapEntity(entity: ServerContract.Types.entity_info): Ship | Warehouse | Container {
|
|
88
|
-
if (entity.type.equals('ship')) {
|
|
89
|
-
return new Ship(entity)
|
|
90
|
-
} else if (entity.type.equals('warehouse')) {
|
|
91
|
-
return new Warehouse(entity)
|
|
92
|
-
} else {
|
|
93
|
-
return new Container(entity)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
49
|
private resolveOwner(owner: NameType | ServerContract.Types.player_row): Name {
|
|
98
50
|
if (typeof owner === 'object' && owner !== null && 'owner' in owner) {
|
|
99
51
|
return owner.owner
|
package/src/managers/epochs.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {BaseManager} from './base'
|
|
3
3
|
import {type EpochInfo, getCurrentEpoch, getEpochInfo} from '../scheduling/epoch'
|
|
4
|
+
import type {ServerContract} from '../contracts'
|
|
4
5
|
|
|
5
6
|
export class EpochsManager extends BaseManager {
|
|
6
7
|
async getCurrentHeight(): Promise<UInt64> {
|
|
@@ -8,6 +9,11 @@ export class EpochsManager extends BaseManager {
|
|
|
8
9
|
return getCurrentEpoch(game)
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
async getFinalizedEpoch(reload = false): Promise<UInt64> {
|
|
13
|
+
const state = await this.getState(reload)
|
|
14
|
+
return state.currentEpoch
|
|
15
|
+
}
|
|
16
|
+
|
|
11
17
|
async getCurrent(): Promise<EpochInfo> {
|
|
12
18
|
const game = await this.getGame()
|
|
13
19
|
const epoch = await this.getCurrentHeight()
|
|
@@ -44,4 +50,38 @@ export class EpochsManager extends BaseManager {
|
|
|
44
50
|
const remaining = await this.getTimeRemaining()
|
|
45
51
|
return durationMs <= remaining
|
|
46
52
|
}
|
|
53
|
+
|
|
54
|
+
async getEpochRow(epoch: UInt64Type): Promise<ServerContract.Types.epoch_row | undefined> {
|
|
55
|
+
const target = UInt64.from(epoch)
|
|
56
|
+
return this.server.table('epoch').get(target)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async getActiveEpochInfo(): Promise<ServerContract.Types.epoch_row | undefined> {
|
|
60
|
+
const rows = await this.server.table('epoch').all()
|
|
61
|
+
if (rows.length === 0) {
|
|
62
|
+
return undefined
|
|
63
|
+
}
|
|
64
|
+
return rows[rows.length - 1]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async getOracles(): Promise<ServerContract.Types.oracle_row[]> {
|
|
68
|
+
return this.server.table('oracles').all()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async getThreshold(): Promise<number> {
|
|
72
|
+
const cfg = await this.server.table('oraclecfg').get()
|
|
73
|
+
return cfg ? Number(cfg.threshold) : 0
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async getCommitsFor(epoch: UInt64Type): Promise<ServerContract.Types.commit_row[]> {
|
|
77
|
+
const target = UInt64.from(epoch)
|
|
78
|
+
const rows = await this.server.table('commit').all()
|
|
79
|
+
return rows.filter((r) => r.epoch.equals(target))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async getRevealsFor(epoch: UInt64Type): Promise<ServerContract.Types.reveal_row[]> {
|
|
83
|
+
const target = UInt64.from(epoch)
|
|
84
|
+
const rows = await this.server.table('reveal').all()
|
|
85
|
+
return rows.filter((r) => r.epoch.equals(target))
|
|
86
|
+
}
|
|
47
87
|
}
|
package/src/managers/index.ts
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
export {GameContext} from './context'
|
|
2
2
|
export {BaseManager} from './base'
|
|
3
3
|
export {EntitiesManager} from './entities'
|
|
4
|
-
export type {
|
|
4
|
+
export type {EntityTypeName} from './entities'
|
|
5
5
|
export {PlayersManager} from './players'
|
|
6
6
|
export {LocationsManager} from './locations'
|
|
7
7
|
export type {LocationStratum} from './locations'
|
|
8
8
|
export {EpochsManager} from './epochs'
|
|
9
9
|
export {ActionsManager} from './actions'
|
|
10
|
+
export {NftManager} from './nft'
|
|
11
|
+
export type {NftConfigForItem} from './nft'
|
|
12
|
+
export {PlotManager} from './plot'
|
|
13
|
+
export type {PlotProgress, PlotProgressInputRow} from './plot'
|
|
14
|
+
export {ConstructionManager} from './construction'
|
|
15
|
+
export type {
|
|
16
|
+
BuildableTarget,
|
|
17
|
+
BuildState,
|
|
18
|
+
SourceEntityRef,
|
|
19
|
+
SourceCargoStack,
|
|
20
|
+
FinalizerEntityRef,
|
|
21
|
+
FinalizerCapability,
|
|
22
|
+
} from './construction-types'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type {UInt16Type} from '@wharfkit/antelope'
|
|
2
2
|
import {BaseManager} from './base'
|
|
3
|
-
import
|
|
3
|
+
import type {CoordinatesType, Distance} from '../types'
|
|
4
4
|
import {hasSystem} from '../utils/system'
|
|
5
5
|
import {findNearbyPlanets} from '../travel/travel'
|
|
6
6
|
import type {ServerContract} from '../contracts'
|
|
@@ -47,22 +47,4 @@ export class LocationsManager extends BaseManager {
|
|
|
47
47
|
reserve: overrideMap.get(s.index) ?? s.reserve,
|
|
48
48
|
}))
|
|
49
49
|
}
|
|
50
|
-
|
|
51
|
-
async getLocationEntity(
|
|
52
|
-
id: UInt64Type
|
|
53
|
-
): Promise<ServerContract.Types.location_row | undefined> {
|
|
54
|
-
const row = await this.server.table('location').get(UInt64.from(id))
|
|
55
|
-
return row ?? undefined
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async getLocationEntityAt(
|
|
59
|
-
coords: CoordinatesType
|
|
60
|
-
): Promise<ServerContract.Types.location_row | undefined> {
|
|
61
|
-
const id = coordsToLocationId(coords)
|
|
62
|
-
return this.getLocationEntity(id)
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async getAllLocationEntities(): Promise<ServerContract.Types.location_row[]> {
|
|
66
|
-
return this.server.table('location').all()
|
|
67
|
-
}
|
|
68
50
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {UInt64, type UInt64Type} from '@wharfkit/antelope'
|
|
2
|
+
import {BaseManager} from './base'
|
|
3
|
+
import type {ServerContract} from '../contracts'
|
|
4
|
+
|
|
5
|
+
export interface NftConfigForItem {
|
|
6
|
+
templateId: number
|
|
7
|
+
schemaName: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class NftManager extends BaseManager {
|
|
11
|
+
private cache = new Map<string, NftConfigForItem | null>()
|
|
12
|
+
|
|
13
|
+
async getNftConfigForItem(itemId: UInt64Type): Promise<NftConfigForItem | undefined> {
|
|
14
|
+
const id = UInt64.from(itemId)
|
|
15
|
+
const key = id.toString()
|
|
16
|
+
if (this.cache.has(key)) {
|
|
17
|
+
return this.cache.get(key) ?? undefined
|
|
18
|
+
}
|
|
19
|
+
const row = (await this.server.table('nftconfig').get(id)) as
|
|
20
|
+
| ServerContract.Types.nftconfig_row
|
|
21
|
+
| undefined
|
|
22
|
+
const result: NftConfigForItem | null = row
|
|
23
|
+
? {templateId: Number(row.template_id), schemaName: String(row.schema_name)}
|
|
24
|
+
: null
|
|
25
|
+
this.cache.set(key, result)
|
|
26
|
+
return result ?? undefined
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import {Name} from '@wharfkit/antelope'
|
|
2
|
+
import {getItem} from '../data/catalog'
|
|
3
|
+
import {getRecipe} from '../data/recipes-runtime'
|
|
4
|
+
import {computeInputMass} from '../derivation/crafting'
|
|
5
|
+
import {calc_craft_duration} from '../capabilities/crafting'
|
|
6
|
+
import {TaskType} from '../types'
|
|
7
|
+
import {BaseManager} from './base'
|
|
8
|
+
import type {ServerContract} from '../contracts'
|
|
9
|
+
import type {BuildableTarget} from './construction-types'
|
|
10
|
+
|
|
11
|
+
export interface PlotProgressInputRow {
|
|
12
|
+
itemId: number
|
|
13
|
+
required: number
|
|
14
|
+
provided: number
|
|
15
|
+
missing: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface PlotProgress {
|
|
19
|
+
targetItemId: number
|
|
20
|
+
rows: PlotProgressInputRow[]
|
|
21
|
+
massProvided: number
|
|
22
|
+
massRequired: number
|
|
23
|
+
isComplete: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class PlotManager extends BaseManager {
|
|
27
|
+
progress(
|
|
28
|
+
plot: ServerContract.Types.entity_row,
|
|
29
|
+
cargo: ServerContract.Types.cargo_row[]
|
|
30
|
+
): PlotProgress {
|
|
31
|
+
const targetItemId = Number(plot.item_id.toString())
|
|
32
|
+
const recipe = getRecipe(targetItemId)
|
|
33
|
+
if (!recipe) {
|
|
34
|
+
throw new Error(`No recipe found for item ${targetItemId}`)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const plotId = plot.id.toString()
|
|
38
|
+
const plotCargo = cargo.filter((c) => c.entity_id.toString() === plotId)
|
|
39
|
+
|
|
40
|
+
const quantityByItemId = new Map<number, number>()
|
|
41
|
+
for (const c of plotCargo) {
|
|
42
|
+
const id = c.item_id.toNumber()
|
|
43
|
+
quantityByItemId.set(
|
|
44
|
+
id,
|
|
45
|
+
(quantityByItemId.get(id) ?? 0) + Number(c.quantity.toString())
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const rows: PlotProgressInputRow[] = recipe.inputs.map((input) => {
|
|
50
|
+
const itemId = input.itemId
|
|
51
|
+
const required = input.quantity
|
|
52
|
+
const provided = quantityByItemId.get(itemId) ?? 0
|
|
53
|
+
const missing = Math.max(0, required - provided)
|
|
54
|
+
return {itemId, required, provided, missing}
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const massRequired = computeInputMass(targetItemId)
|
|
58
|
+
const massProvided = rows.reduce((sum, r) => {
|
|
59
|
+
const item = getItem(r.itemId)
|
|
60
|
+
return sum + item.mass * r.provided
|
|
61
|
+
}, 0)
|
|
62
|
+
const isComplete = rows.every((r) => r.missing === 0)
|
|
63
|
+
|
|
64
|
+
return {targetItemId, rows, massProvided, massRequired, isComplete}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
buildableTarget(
|
|
68
|
+
plot: ServerContract.Types.entity_row,
|
|
69
|
+
cargo: ServerContract.Types.cargo_row[],
|
|
70
|
+
activeTask?: ServerContract.Types.task
|
|
71
|
+
): BuildableTarget {
|
|
72
|
+
const progress = this.progress(plot, cargo)
|
|
73
|
+
const targetItemId = Number(plot.item_id.toString())
|
|
74
|
+
const targetItem = getItem(targetItemId)
|
|
75
|
+
const recipe = getRecipe(targetItemId)
|
|
76
|
+
if (!recipe) {
|
|
77
|
+
throw new Error(`Plot target item ${targetItemId} has no recipe`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
let state: BuildableTarget['state']
|
|
81
|
+
const taskType = activeTask?.type.toNumber()
|
|
82
|
+
if (taskType === TaskType.CLAIMPLOT) {
|
|
83
|
+
state = 'initializing'
|
|
84
|
+
} else if (taskType === TaskType.BUILDPLOT) {
|
|
85
|
+
state = 'finalizing'
|
|
86
|
+
} else if (progress.isComplete) {
|
|
87
|
+
state = 'ready'
|
|
88
|
+
} else {
|
|
89
|
+
state = 'accepting'
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
entityId: plot.id,
|
|
94
|
+
ownerName: plot.owner,
|
|
95
|
+
coordinates: plot.coordinates,
|
|
96
|
+
targetItemId,
|
|
97
|
+
targetItem,
|
|
98
|
+
state,
|
|
99
|
+
recipe,
|
|
100
|
+
progress,
|
|
101
|
+
finalizeAction: Name.from('buildplot'),
|
|
102
|
+
finalizerCapability: 'crafter',
|
|
103
|
+
activeTask,
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
canBuild(
|
|
108
|
+
plot: ServerContract.Types.entity_row,
|
|
109
|
+
cargo: ServerContract.Types.cargo_row[]
|
|
110
|
+
): boolean {
|
|
111
|
+
return this.progress(plot, cargo).isComplete
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
timeToComplete(
|
|
115
|
+
plot: ServerContract.Types.entity_info,
|
|
116
|
+
crafter: ServerContract.Types.crafter_stats
|
|
117
|
+
): number {
|
|
118
|
+
const capacity = Number(plot.capacity?.toString() ?? '0')
|
|
119
|
+
const speed = Number(crafter.speed.toString())
|
|
120
|
+
if (speed === 0) return 0
|
|
121
|
+
return calc_craft_duration(speed, capacity).toNumber()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ABI,
|
|
3
|
+
type ABIDef,
|
|
4
|
+
Action,
|
|
5
|
+
type APIClient,
|
|
6
|
+
type NameType,
|
|
7
|
+
Name,
|
|
8
|
+
PermissionLevel,
|
|
9
|
+
UInt64,
|
|
10
|
+
} from '@wharfkit/antelope'
|
|
11
|
+
import {deserializeAtomicData, type SchemaField} from './atomicdata'
|
|
12
|
+
import {deserializeAsset, type NFTCargoItem, type NFTModuleSlot} from './deserializers'
|
|
13
|
+
import type {ImmutableEntry} from './buildImmutableData'
|
|
14
|
+
|
|
15
|
+
const PLACEHOLDER_AUTH = PermissionLevel.from({
|
|
16
|
+
actor: '............1',
|
|
17
|
+
permission: '............2',
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
export const ATOMICASSETS_ACCOUNT = 'atomicassets'
|
|
21
|
+
export const SHIPLOAD_COLLECTION = 'shipload'
|
|
22
|
+
|
|
23
|
+
const ATOMIC_ATTRIBUTE_VARIANT_NAME =
|
|
24
|
+
'variant_int8_int16_int32_int64_uint8_uint16_uint32_uint64_float32_float64_string_INT8_VEC_INT16_VEC_INT32_VEC_INT64_VEC_UINT8_VEC_UINT16_VEC_UINT32_VEC_UINT64_VEC_FLOAT_VEC_DOUBLE_VEC_STRING_VEC'
|
|
25
|
+
|
|
26
|
+
const MINTASSET_ABI_DEF: ABIDef = {
|
|
27
|
+
version: 'eosio::abi/1.2',
|
|
28
|
+
types: [
|
|
29
|
+
{new_type_name: 'ATOMIC_ATTRIBUTE', type: ATOMIC_ATTRIBUTE_VARIANT_NAME},
|
|
30
|
+
{new_type_name: 'ATTRIBUTE_MAP', type: 'pair_string_ATOMIC_ATTRIBUTE[]'},
|
|
31
|
+
{new_type_name: 'INT8_VEC', type: 'bytes'},
|
|
32
|
+
{new_type_name: 'INT16_VEC', type: 'int16[]'},
|
|
33
|
+
{new_type_name: 'INT32_VEC', type: 'int32[]'},
|
|
34
|
+
{new_type_name: 'INT64_VEC', type: 'int64[]'},
|
|
35
|
+
{new_type_name: 'UINT8_VEC', type: 'bytes'},
|
|
36
|
+
{new_type_name: 'UINT16_VEC', type: 'uint16[]'},
|
|
37
|
+
{new_type_name: 'UINT32_VEC', type: 'uint32[]'},
|
|
38
|
+
{new_type_name: 'UINT64_VEC', type: 'uint64[]'},
|
|
39
|
+
{new_type_name: 'FLOAT_VEC', type: 'float32[]'},
|
|
40
|
+
{new_type_name: 'DOUBLE_VEC', type: 'float64[]'},
|
|
41
|
+
{new_type_name: 'STRING_VEC', type: 'string[]'},
|
|
42
|
+
],
|
|
43
|
+
structs: [
|
|
44
|
+
{
|
|
45
|
+
name: 'pair_string_ATOMIC_ATTRIBUTE',
|
|
46
|
+
base: '',
|
|
47
|
+
fields: [
|
|
48
|
+
{name: 'first', type: 'string'},
|
|
49
|
+
{name: 'second', type: 'ATOMIC_ATTRIBUTE'},
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'mintasset',
|
|
54
|
+
base: '',
|
|
55
|
+
fields: [
|
|
56
|
+
{name: 'authorized_minter', type: 'name'},
|
|
57
|
+
{name: 'collection_name', type: 'name'},
|
|
58
|
+
{name: 'schema_name', type: 'name'},
|
|
59
|
+
{name: 'template_id', type: 'int32'},
|
|
60
|
+
{name: 'new_asset_owner', type: 'name'},
|
|
61
|
+
{name: 'immutable_data', type: 'ATTRIBUTE_MAP'},
|
|
62
|
+
{name: 'mutable_data', type: 'ATTRIBUTE_MAP'},
|
|
63
|
+
{name: 'tokens_to_back', type: 'asset[]'},
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
actions: [{name: 'mintasset', type: 'mintasset', ricardian_contract: ''}],
|
|
68
|
+
variants: [
|
|
69
|
+
{
|
|
70
|
+
name: ATOMIC_ATTRIBUTE_VARIANT_NAME,
|
|
71
|
+
types: [
|
|
72
|
+
'int8',
|
|
73
|
+
'int16',
|
|
74
|
+
'int32',
|
|
75
|
+
'int64',
|
|
76
|
+
'uint8',
|
|
77
|
+
'uint16',
|
|
78
|
+
'uint32',
|
|
79
|
+
'uint64',
|
|
80
|
+
'float32',
|
|
81
|
+
'float64',
|
|
82
|
+
'string',
|
|
83
|
+
'INT8_VEC',
|
|
84
|
+
'INT16_VEC',
|
|
85
|
+
'INT32_VEC',
|
|
86
|
+
'INT64_VEC',
|
|
87
|
+
'UINT8_VEC',
|
|
88
|
+
'UINT16_VEC',
|
|
89
|
+
'UINT32_VEC',
|
|
90
|
+
'UINT64_VEC',
|
|
91
|
+
'FLOAT_VEC',
|
|
92
|
+
'DOUBLE_VEC',
|
|
93
|
+
'STRING_VEC',
|
|
94
|
+
],
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface MintAssetParams {
|
|
100
|
+
authorizedMinter: NameType
|
|
101
|
+
collectionName: NameType
|
|
102
|
+
schemaName: NameType
|
|
103
|
+
templateId: number
|
|
104
|
+
newAssetOwner: NameType
|
|
105
|
+
immutableData: ImmutableEntry[]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const MINTASSET_ABI = ABI.from(MINTASSET_ABI_DEF)
|
|
109
|
+
|
|
110
|
+
export function buildMintAssetAction(params: MintAssetParams): Action {
|
|
111
|
+
return Action.from(
|
|
112
|
+
{
|
|
113
|
+
account: Name.from(ATOMICASSETS_ACCOUNT),
|
|
114
|
+
name: Name.from('mintasset'),
|
|
115
|
+
authorization: [PLACEHOLDER_AUTH],
|
|
116
|
+
data: {
|
|
117
|
+
authorized_minter: Name.from(params.authorizedMinter),
|
|
118
|
+
collection_name: Name.from(params.collectionName),
|
|
119
|
+
schema_name: Name.from(params.schemaName),
|
|
120
|
+
template_id: params.templateId,
|
|
121
|
+
new_asset_owner: Name.from(params.newAssetOwner),
|
|
122
|
+
immutable_data: params.immutableData,
|
|
123
|
+
mutable_data: [],
|
|
124
|
+
tokens_to_back: [],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
MINTASSET_ABI
|
|
128
|
+
)
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export interface AtomicAssetRow {
|
|
132
|
+
asset_id: string
|
|
133
|
+
collection_name: string
|
|
134
|
+
schema_name: string
|
|
135
|
+
template_id: number
|
|
136
|
+
ram_payer?: string
|
|
137
|
+
backed_tokens?: string[]
|
|
138
|
+
immutable_serialized_data: string | number[]
|
|
139
|
+
mutable_serialized_data?: string | number[]
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface AtomicSchemaRow {
|
|
143
|
+
schema_name: string
|
|
144
|
+
format: SchemaField[]
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface FetchAssetsOptions {
|
|
148
|
+
collection?: NameType
|
|
149
|
+
pageSize?: number
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function fetchAtomicAssetsForOwner(
|
|
153
|
+
client: APIClient,
|
|
154
|
+
owner: NameType,
|
|
155
|
+
opts: FetchAssetsOptions = {}
|
|
156
|
+
): Promise<AtomicAssetRow[]> {
|
|
157
|
+
const collection = opts.collection ? String(Name.from(opts.collection)) : undefined
|
|
158
|
+
const pageSize = opts.pageSize ?? 1000
|
|
159
|
+
const out: AtomicAssetRow[] = []
|
|
160
|
+
let lower: UInt64 | undefined
|
|
161
|
+
while (true) {
|
|
162
|
+
const res = await client.v1.chain.get_table_rows({
|
|
163
|
+
code: Name.from(ATOMICASSETS_ACCOUNT),
|
|
164
|
+
scope: String(Name.from(owner)),
|
|
165
|
+
table: Name.from('assets'),
|
|
166
|
+
limit: pageSize,
|
|
167
|
+
lower_bound: lower,
|
|
168
|
+
json: true,
|
|
169
|
+
})
|
|
170
|
+
for (const row of res.rows as AtomicAssetRow[]) {
|
|
171
|
+
if (!collection || row.collection_name === collection) out.push(row)
|
|
172
|
+
}
|
|
173
|
+
if (!res.more) break
|
|
174
|
+
lower = UInt64.from(String(res.next_key))
|
|
175
|
+
}
|
|
176
|
+
return out
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export async function fetchAtomicSchemas(
|
|
180
|
+
client: APIClient,
|
|
181
|
+
collection: NameType
|
|
182
|
+
): Promise<AtomicSchemaRow[]> {
|
|
183
|
+
const out: AtomicSchemaRow[] = []
|
|
184
|
+
let lower: Name | undefined
|
|
185
|
+
while (true) {
|
|
186
|
+
const res = await client.v1.chain.get_table_rows({
|
|
187
|
+
code: Name.from(ATOMICASSETS_ACCOUNT),
|
|
188
|
+
scope: String(Name.from(collection)),
|
|
189
|
+
table: Name.from('schemas'),
|
|
190
|
+
limit: 100,
|
|
191
|
+
lower_bound: lower,
|
|
192
|
+
json: true,
|
|
193
|
+
})
|
|
194
|
+
for (const row of res.rows as AtomicSchemaRow[]) out.push(row)
|
|
195
|
+
if (!res.more) break
|
|
196
|
+
lower = Name.from(String(res.next_key))
|
|
197
|
+
}
|
|
198
|
+
return out
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export interface DecodedAtomicAsset {
|
|
202
|
+
asset_id: bigint
|
|
203
|
+
schema_name: string
|
|
204
|
+
template_id: number
|
|
205
|
+
item_id: number
|
|
206
|
+
quantity: number
|
|
207
|
+
stats: string
|
|
208
|
+
origin_x: bigint
|
|
209
|
+
origin_y: bigint
|
|
210
|
+
modules?: NFTModuleSlot[]
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function decodeAtomicAsset(
|
|
214
|
+
asset: AtomicAssetRow,
|
|
215
|
+
schemaFormat: SchemaField[],
|
|
216
|
+
itemId: number
|
|
217
|
+
): DecodedAtomicAsset {
|
|
218
|
+
const data = deserializeAtomicData(asset.immutable_serialized_data, schemaFormat)
|
|
219
|
+
const cargo: NFTCargoItem = deserializeAsset(data, itemId)
|
|
220
|
+
return {
|
|
221
|
+
asset_id: BigInt(String(asset.asset_id)),
|
|
222
|
+
schema_name: String(asset.schema_name),
|
|
223
|
+
template_id: Number(asset.template_id),
|
|
224
|
+
item_id: cargo.item_id,
|
|
225
|
+
quantity: cargo.quantity,
|
|
226
|
+
stats: cargo.stats,
|
|
227
|
+
origin_x: BigInt(String(data.origin_x ?? 0)),
|
|
228
|
+
origin_y: BigInt(String(data.origin_y ?? 0)),
|
|
229
|
+
modules: cargo.modules,
|
|
230
|
+
}
|
|
231
|
+
}
|