@shipload/sdk 1.0.0-next.65 → 1.0.0-next.66

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.
Files changed (79) hide show
  1. package/lib/shipload.d.ts +698 -316
  2. package/lib/shipload.js +2473 -1235
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +2392 -1216
  5. package/lib/shipload.m.js.map +1 -1
  6. package/lib/testing.d.ts +205 -146
  7. package/lib/testing.js +846 -556
  8. package/lib/testing.js.map +1 -1
  9. package/lib/testing.m.js +846 -556
  10. package/lib/testing.m.js.map +1 -1
  11. package/package.json +1 -1
  12. package/src/capabilities/crafting.test.ts +51 -6
  13. package/src/capabilities/crafting.ts +19 -4
  14. package/src/capabilities/gathering.ts +2 -2
  15. package/src/capabilities/storage.test.ts +26 -0
  16. package/src/capabilities/storage.ts +6 -6
  17. package/src/contracts/fund.ts +79 -2
  18. package/src/contracts/platform.ts +10 -1
  19. package/src/contracts/server.ts +467 -331
  20. package/src/data/charters.json +325 -127
  21. package/src/data/entities.json +24 -24
  22. package/src/data/items.json +114 -114
  23. package/src/data/kind-registry.json +3 -3
  24. package/src/data/kind-registry.ts +5 -0
  25. package/src/data/recipes.json +56 -95
  26. package/src/derivation/build-methods.test.ts +59 -1
  27. package/src/derivation/build-methods.ts +2 -0
  28. package/src/derivation/capabilities.ts +7 -7
  29. package/src/derivation/strata.ts +5 -3
  30. package/src/derivation/tiers.ts +5 -5
  31. package/src/entity/hydrate.test.ts +156 -0
  32. package/src/entity/hydrate.ts +86 -0
  33. package/src/errors.ts +9 -0
  34. package/src/format.ts +15 -13
  35. package/src/index-module.ts +32 -5
  36. package/src/influence/ballot.test.ts +103 -0
  37. package/src/influence/ballot.ts +98 -0
  38. package/src/influence/charter-metadata.test.ts +136 -0
  39. package/src/influence/charter-metadata.ts +236 -0
  40. package/src/influence/charters.test.ts +51 -65
  41. package/src/influence/charters.ts +70 -40
  42. package/src/influence/civic.test.ts +278 -0
  43. package/src/influence/civic.ts +269 -0
  44. package/src/influence/constants.ts +30 -9
  45. package/src/influence/decomp.ts +15 -15
  46. package/src/influence/duration.ts +42 -6
  47. package/src/influence/index.ts +49 -6
  48. package/src/influence/influence.test.ts +76 -9
  49. package/src/influence/valuation.ts +17 -17
  50. package/src/managers/actions.ts +65 -37
  51. package/src/managers/base.ts +4 -0
  52. package/src/managers/context.ts +3 -1
  53. package/src/managers/index.ts +4 -2
  54. package/src/managers/influence.test.ts +18 -20
  55. package/src/managers/influence.ts +137 -84
  56. package/src/managers/jobs.test.ts +2 -2
  57. package/src/managers/jobs.ts +4 -4
  58. package/src/nft/description.ts +10 -11
  59. package/src/planner/index.ts +54 -0
  60. package/src/planner/planner.test.ts +127 -2
  61. package/src/resolution/display-name.ts +1 -1
  62. package/src/scheduling/availability.test.ts +113 -0
  63. package/src/scheduling/availability.ts +48 -8
  64. package/src/scheduling/jobs.ts +1 -1
  65. package/src/scheduling/projection.ts +2 -16
  66. package/src/scheduling/task-cargo.test.ts +62 -1
  67. package/src/scheduling/task-cargo.ts +25 -10
  68. package/src/scheduling/task-effects.test.ts +35 -0
  69. package/src/scheduling/task-effects.ts +34 -0
  70. package/src/scheduling/unwrap.test.ts +3 -3
  71. package/src/scheduling/unwrap.ts +3 -3
  72. package/src/shipload.ts +22 -3
  73. package/src/travel/reach.test.ts +86 -0
  74. package/src/travel/reach.ts +23 -10
  75. package/src/travel/route-build.test.ts +63 -0
  76. package/src/travel/route-build.ts +60 -0
  77. package/src/travel/travel.ts +2 -1
  78. package/src/types.ts +6 -2
  79. package/src/utils/hash.ts +18 -2
@@ -1,5 +1,6 @@
1
1
  import {describe, expect, test} from 'bun:test'
2
- import {Checksum256} from '@wharfkit/antelope'
2
+ import {Checksum256, UInt8, UInt16, UInt64} from '@wharfkit/antelope'
3
+ import type {ServerContract} from '../contracts'
3
4
  import {ITEM_ORE_T1, ITEM_PLATE, ITEM_CRYSTAL_T1} from '../data/item-ids'
4
5
  import {categoryIndex} from './categories'
5
6
  import {
@@ -19,7 +20,7 @@ import {
19
20
  popcount5,
20
21
  } from './demand'
21
22
  import {findDecomp, DECOMP_REGISTRY} from './decomp'
22
- import {contributeDuration} from './duration'
23
+ import {depotTransferDuration, contributeDuration} from './duration'
23
24
  import {getStatCount, statsSumSq} from './quality'
24
25
  import {pricingFromWeights, valueCargoItem, valueContribution} from './valuation'
25
26
  import {citizenryName, citizenryPatternCount} from './citizenry'
@@ -135,7 +136,7 @@ describe('decomposition', () => {
135
136
  for (let i = 1; i < DECOMP_REGISTRY.length; i++) {
136
137
  expect(DECOMP_REGISTRY[i].itemId).toBeGreaterThan(DECOMP_REGISTRY[i - 1].itemId)
137
138
  }
138
- expect(DECOMP_REGISTRY.length).toBe(57)
139
+ expect(DECOMP_REGISTRY.length).toBe(56)
139
140
  })
140
141
 
141
142
  test('the retired Workshop has no decomposition entry', () => {
@@ -145,7 +146,7 @@ describe('decomposition', () => {
145
146
  test('buckets are sorted and hold only raw resources', () => {
146
147
  const entry = findDecomp(ITEM_PLATE)
147
148
  if (!entry) throw new Error('Plate has no decomposition entry')
148
- expect(entry.processedKg).toBeGreaterThan(0)
149
+ expect(entry.processedMass).toBeGreaterThan(0)
149
150
  for (let i = 1; i < entry.buckets.length; i++) {
150
151
  const prev = entry.buckets[i - 1]
151
152
  const cur = entry.buckets[i]
@@ -250,18 +251,18 @@ describe('valuation', () => {
250
251
 
251
252
  describe('contribution duration', () => {
252
253
  test('grows with mass and never falls below a single tick', () => {
253
- expect(contributeDuration(1_000)).toBeGreaterThan(0)
254
- expect(contributeDuration(1_000_000)).toBeGreaterThan(contributeDuration(1_000))
254
+ expect(contributeDuration(10)).toBeGreaterThan(0)
255
+ expect(contributeDuration(10_000)).toBeGreaterThan(contributeDuration(10))
255
256
  })
256
257
 
257
258
  test('splitting a haul costs more than one trip', () => {
258
- const single = contributeDuration(100_000_000)
259
- const hundred = contributeDuration(1_000_000) * 100
259
+ const single = contributeDuration(1_000_000)
260
+ const hundred = contributeDuration(10_000) * 100
260
261
  expect(hundred).toBeGreaterThan(single)
261
262
  })
262
263
 
263
264
  test('ground level is floored at the base orbital climb', () => {
264
- expect(contributeDuration(1_000, 0)).toBe(contributeDuration(1_000, 800))
265
+ expect(contributeDuration(10, 0)).toBe(contributeDuration(10, 800))
265
266
  })
266
267
  })
267
268
 
@@ -315,3 +316,69 @@ describe('scales', () => {
315
316
  expect(NEED_FP_SCALE % INFLUENCE_ATOMIC_PER_POINT).toBe(0)
316
317
  })
317
318
  })
319
+
320
+ describe('depot transfer duration', () => {
321
+ type ModuleEntry = ServerContract.Types.module_entry
322
+ const DEPOT_ITEM = 10219
323
+ const LOADER_T1 = 10103
324
+
325
+ function makeModuleEntry(itemId: number, stats: bigint): ModuleEntry {
326
+ return {
327
+ type: UInt8.from(0),
328
+ installed: {item_id: UInt16.from(itemId), stats: UInt64.from(stats)},
329
+ } as unknown as ModuleEntry
330
+ }
331
+ function emptySlot(): ModuleEntry {
332
+ return {type: UInt8.from(0)} as unknown as ModuleEntry
333
+ }
334
+
335
+ // A spawned depot: loader in slot 0, four empty bays after it.
336
+ const depotWithLoader = (): ModuleEntry[] => [
337
+ makeModuleEntry(LOADER_T1, packStats(500)),
338
+ emptySlot(),
339
+ emptySlot(),
340
+ emptySlot(),
341
+ emptySlot(),
342
+ ]
343
+ const params = (overrides: Record<string, unknown> = {}) => ({
344
+ depotModules: depotWithLoader(),
345
+ depotItemId: DEPOT_ITEM,
346
+ depotKind: 'depot',
347
+ depotZ: 0,
348
+ shipKind: 'ship',
349
+ shipZ: 0,
350
+ cargoMass: 100,
351
+ ...overrides,
352
+ })
353
+
354
+ test('drives off the depot loader, not the ship', () => {
355
+ expect(depotTransferDuration(params())).toBeGreaterThan(0)
356
+ })
357
+
358
+ test('grows with cargo mass', () => {
359
+ expect(depotTransferDuration(params({cargoMass: 10_000}))).toBeGreaterThan(
360
+ depotTransferDuration(params({cargoMass: 100}))
361
+ )
362
+ })
363
+
364
+ test('empty cargo costs nothing', () => {
365
+ expect(depotTransferDuration(params({cargoMass: 0}))).toBe(0)
366
+ })
367
+
368
+ test('a depot with no loader installed cannot transfer', () => {
369
+ expect(depotTransferDuration(params({depotModules: [emptySlot()]}))).toBe(0)
370
+ })
371
+
372
+ test('co-located transfers are floored at the orbital minimum distance', () => {
373
+ // max(planetary 100, orbital 200) = 200, so anything under 200 reads as 200
374
+ const touching = depotTransferDuration(params({shipZ: 0, depotZ: 0}))
375
+ const under = depotTransferDuration(params({shipZ: 150, depotZ: 0}))
376
+ const over = depotTransferDuration(params({shipZ: 400, depotZ: 0}))
377
+ expect(under).toBe(touching)
378
+ expect(over).toBeGreaterThan(touching)
379
+ })
380
+
381
+ test('never reports zero for real cargo', () => {
382
+ expect(depotTransferDuration(params({cargoMass: 1}))).toBeGreaterThanOrEqual(1)
383
+ })
384
+ })
@@ -1,14 +1,14 @@
1
1
  import {getItem} from '../data/catalog'
2
+ import {MASS_UNITS_PER_TONNE} from '../types'
2
3
  import {categoryIndex} from './categories'
3
4
  import {
4
5
  INFLUENCE_ATOMIC_PER_POINT,
5
- INFLUENCE_MASS_KG_MAX,
6
+ INFLUENCE_MASS_MAX,
6
7
  INFLUENCE_NEED_FP_MAX,
7
8
  INFLUENCE_WEIGHT_FP_MAX,
8
- MASS_KG_PER_TONNE,
9
9
  NEED_FP_SCALE,
10
10
  WEIGHT_FP_SCALE,
11
- W_EFF_ATOMIC_PER_KG,
11
+ W_EFF_ATOMIC_PER_UNIT,
12
12
  } from './constants'
13
13
  import {findDecomp} from './decomp'
14
14
  import type {DemandView} from './demand'
@@ -29,16 +29,16 @@ export interface ValuedItem {
29
29
  }
30
30
 
31
31
  export function weightedQualityAtomic(
32
- weightedKgFp: bigint,
32
+ weightedMassFp: bigint,
33
33
  sumSq: number,
34
34
  nStats: number,
35
35
  d1: number,
36
36
  needFp: bigint
37
37
  ): bigint {
38
38
  if (nStats <= 0 || d1 <= 0) throw new Error('influence: invalid quality divisor')
39
- const num = weightedKgFp * BigInt(sumSq) * needFp
39
+ const num = weightedMassFp * BigInt(sumSq) * needFp
40
40
  const den =
41
- (BigInt(MASS_KG_PER_TONNE) *
41
+ (BigInt(MASS_UNITS_PER_TONNE) *
42
42
  BigInt(WEIGHT_FP_SCALE) *
43
43
  BigInt(nStats) *
44
44
  BigInt(d1) *
@@ -48,34 +48,34 @@ export function weightedQualityAtomic(
48
48
  }
49
49
 
50
50
  export function resourceValueAtomic(
51
- massKg: bigint,
51
+ mass: bigint,
52
52
  weightFp: bigint,
53
53
  sumSq: number,
54
54
  nStats: number,
55
55
  d1: number,
56
56
  needFp: bigint
57
57
  ): bigint {
58
- if (massKg > INFLUENCE_MASS_KG_MAX) throw new Error('influence: mass out of range')
58
+ if (mass > INFLUENCE_MASS_MAX) throw new Error('influence: mass out of range')
59
59
  if (weightFp > INFLUENCE_WEIGHT_FP_MAX) throw new Error('influence: weight out of range')
60
60
  if (needFp > INFLUENCE_NEED_FP_MAX) throw new Error('influence: need out of range')
61
- return weightedQualityAtomic(massKg * weightFp, sumSq, nStats, d1, needFp)
61
+ return weightedQualityAtomic(mass * weightFp, sumSq, nStats, d1, needFp)
62
62
  }
63
63
 
64
64
  export function componentBaseAtomic(
65
- weightedRawKgFp: bigint,
65
+ weightedRawMassFp: bigint,
66
66
  sumSq: number,
67
67
  nStats: number,
68
68
  d1: number
69
69
  ): bigint {
70
- return weightedQualityAtomic(weightedRawKgFp, sumSq, nStats, d1, BigInt(NEED_FP_SCALE))
70
+ return weightedQualityAtomic(weightedRawMassFp, sumSq, nStats, d1, BigInt(NEED_FP_SCALE))
71
71
  }
72
72
 
73
- export function componentEffortAtomic(processedKgPerUnit: number, quantity: number): bigint {
74
- const processed = BigInt(processedKgPerUnit) * BigInt(quantity)
75
- if (processed > INFLUENCE_MASS_KG_MAX) {
73
+ export function componentEffortAtomic(processedMassPerUnit: number, quantity: number): bigint {
74
+ const processed = BigInt(processedMassPerUnit) * BigInt(quantity)
75
+ if (processed > INFLUENCE_MASS_MAX) {
76
76
  throw new Error('influence: processed mass out of range')
77
77
  }
78
- return processed * W_EFF_ATOMIC_PER_KG
78
+ return processed * W_EFF_ATOMIC_PER_UNIT
79
79
  }
80
80
 
81
81
  export function valueCargoItem(
@@ -114,14 +114,14 @@ export function valueCargoItem(
114
114
 
115
115
  let weighted = 0n
116
116
  for (const bucket of entry.buckets) {
117
- weighted += BigInt(bucket.rawKg) * pricing.weight(bucket.category, bucket.tier)
117
+ weighted += BigInt(bucket.rawMass) * pricing.weight(bucket.category, bucket.tier)
118
118
  }
119
119
 
120
120
  const perUnit = componentBaseAtomic(weighted, sumSq, nStats, pricing.d1)
121
121
  const total = perUnit * BigInt(item.quantity)
122
122
  if (total > UINT64_MAX) throw new Error('influence: component value overflow')
123
123
 
124
- const withEffort = total + componentEffortAtomic(entry.processedKg, item.quantity)
124
+ const withEffort = total + componentEffortAtomic(entry.processedMass, item.quantity)
125
125
  if (withEffort > UINT64_MAX) throw new Error('influence: component value overflow')
126
126
  return withEffort
127
127
  }
@@ -25,8 +25,9 @@ import {ServerContract, TokenContract} from '../contracts'
25
25
  import {ATOMICASSETS_ABI, SHIPLOAD_COLLECTION} from '../nft/atomicassets'
26
26
  import {getItem} from '../data/catalog'
27
27
 
28
- const CHARGE_K = 1n
29
- const ENERGY_DIVISOR = 1_000_000n
28
+ const CHARGE_K = 100n
29
+ const ENERGY_DIVISOR = 10n
30
+ const ENERGY_FLOOR = 1_000n
30
31
  const UINT32_MAX = 4_294_967_295
31
32
  const UINT32_MAX_BIGINT = 4_294_967_295n
32
33
  const UINT32_MOD = 4_294_967_296n
@@ -99,6 +100,12 @@ function clampLaunchResult(value: bigint): number {
99
100
  return Number(value)
100
101
  }
101
102
 
103
+ function clampEnergyResult(value: bigint): number {
104
+ if (value < ENERGY_FLOOR) return Number(ENERGY_FLOOR)
105
+ if (value > UINT32_MAX_BIGINT) return UINT32_MAX
106
+ return Number(value)
107
+ }
108
+
102
109
  function toUint32(value: bigint): bigint {
103
110
  return value % UINT32_MOD
104
111
  }
@@ -133,7 +140,8 @@ function calcPayloadMass(items: ServerContract.ActionParams.Type.cargo_item[]):
133
140
 
134
141
  function calcChargeTime(chargeRate: number, mass: bigint): number {
135
142
  const rate = BigInt(chargeRate || 1)
136
- return clampLaunchResult((mass * CHARGE_K) / rate)
143
+ const t = (mass * CHARGE_K) / rate
144
+ return clampLaunchResult(t + 1n)
137
145
  }
138
146
 
139
147
  function calcFlightTime(velocity: number, distance: bigint): number {
@@ -145,7 +153,7 @@ function calcLaunchEnergy(drain: number, mass: bigint, distance: bigint): number
145
153
  const e =
146
154
  saturatingMul(saturatingMul(mass, distance / PRECISION_BIGINT), BigInt(drain)) /
147
155
  ENERGY_DIVISOR
148
- return clampLaunchResult(e)
156
+ return clampEnergyResult(e)
149
157
  }
150
158
 
151
159
  function calcMaxReach(energyBudget: bigint, mass: bigint, drain: number): bigint {
@@ -524,58 +532,51 @@ export class ActionsManager extends BaseManager {
524
532
  return this.server.action('clustercraft', params)
525
533
  }
526
534
 
527
- claimjob(jobId: UInt64Type, shipId: UInt64Type): Action {
528
- const params: ServerContract.ActionParams.claimjob = {
535
+ claimcraft(jobId: UInt64Type, shipId: UInt64Type): Action {
536
+ const params: ServerContract.ActionParams.claimcraft = {
529
537
  job_id: UInt64.from(jobId),
530
538
  ship_id: UInt64.from(shipId),
531
539
  }
532
- return this.server.action('claimjob', params)
540
+ return this.server.action('claimcraft', params)
533
541
  }
534
542
 
535
- canceljob(jobId: UInt64Type, shipId: UInt64Type): Action {
536
- const params: ServerContract.ActionParams.canceljob = {
543
+ cancelcraft(jobId: UInt64Type, shipId: UInt64Type): Action {
544
+ const params: ServerContract.ActionParams.cancelcraft = {
537
545
  job_id: UInt64.from(jobId),
538
546
  ship_id: UInt64.from(shipId),
539
547
  }
540
- return this.server.action('canceljob', params)
548
+ return this.server.action('cancelcraft', params)
541
549
  }
542
550
 
543
- upgradejob(
551
+ buildjob(
544
552
  targetId: UInt64Type,
545
553
  dockId: UInt64Type,
554
+ slot: UInt8Type,
546
555
  targetItemId: UInt16Type,
547
556
  inputs: ServerContract.ActionParams.Type.cargo_item[]
548
557
  ): Action {
549
- const params: ServerContract.ActionParams.upgradejob = {
558
+ const params: ServerContract.ActionParams.buildjob = {
550
559
  target_id: UInt64.from(targetId),
551
560
  dock_id: UInt64.from(dockId),
561
+ slot: UInt8.from(slot),
552
562
  target_item_id: UInt16.from(targetItemId),
553
563
  inputs,
554
564
  }
555
- return this.server.action('upgradejob', params)
565
+ return this.server.action('buildjob', params)
556
566
  }
557
567
 
558
- claimupgrade(jobId: UInt64Type): Action {
559
- const params: ServerContract.ActionParams.claimupgrade = {
568
+ claimbuild(jobId: UInt64Type): Action {
569
+ const params: ServerContract.ActionParams.claimbuild = {
560
570
  job_id: UInt64.from(jobId),
561
571
  }
562
- return this.server.action('claimupgrade', params)
572
+ return this.server.action('claimbuild', params)
563
573
  }
564
574
 
565
- cancelupgrade(jobId: UInt64Type): Action {
566
- const params: ServerContract.ActionParams.cancelupgrade = {
575
+ cancelbuild(jobId: UInt64Type): Action {
576
+ const params: ServerContract.ActionParams.cancelbuild = {
567
577
  job_id: UInt64.from(jobId),
568
578
  }
569
- return this.server.action('cancelupgrade', params)
570
- }
571
-
572
- setsocket(workshopId: UInt64Type, slot: UInt8Type, open: boolean): Action {
573
- const params: ServerContract.ActionParams.setsocket = {
574
- workshop_id: UInt64.from(workshopId),
575
- slot: UInt8.from(slot),
576
- open,
577
- }
578
- return this.server.action('setsocket', params)
579
+ return this.server.action('cancelbuild', params)
579
580
  }
580
581
 
581
582
  blend(entityId: UInt64Type, inputs: ServerContract.ActionParams.Type.cargo_item[]): Action {
@@ -844,6 +845,12 @@ export class ActionsManager extends BaseManager {
844
845
  return actions
845
846
  }
846
847
 
848
+ setunwrapmin(assetId: UInt64Type): Action {
849
+ return this.server.action('setunwrapmin', {
850
+ asset_id: UInt64.from(assetId),
851
+ })
852
+ }
853
+
847
854
  placecargo(owner: NameType, hostId: UInt64Type, assetId: UInt64Type): Action {
848
855
  return this.server.action('placecargo', {
849
856
  owner: Name.from(owner),
@@ -982,6 +989,23 @@ export class ActionsManager extends BaseManager {
982
989
  })
983
990
  }
984
991
 
992
+ addFundToken(tokenContract: NameType, tokenSymbol: Asset.SymbolType): Action {
993
+ return this.fund.action('addtoken', {
994
+ token_contract: Name.from(tokenContract),
995
+ token_symbol: Asset.Symbol.from(tokenSymbol),
996
+ })
997
+ }
998
+
999
+ removeFundToken(tokenContract: NameType): Action {
1000
+ return this.fund.action('deltoken', {
1001
+ token_contract: Name.from(tokenContract),
1002
+ })
1003
+ }
1004
+
1005
+ collectFund(): Action {
1006
+ return this.fund.action('collect', {})
1007
+ }
1008
+
985
1009
  found(player: NameType, entityId: UInt64Type, location: CoordinatesType): Action {
986
1010
  return this.server.action('found', {
987
1011
  player: Name.from(player),
@@ -1043,18 +1067,22 @@ export class ActionsManager extends BaseManager {
1043
1067
  })
1044
1068
  }
1045
1069
 
1046
- votecharter(player: NameType, location: CoordinatesType, nodeId: UInt32Type): Action {
1047
- return this.server.action('votecharter', {
1048
- player: Name.from(player),
1049
- x: Int64.from(location.x),
1050
- y: Int64.from(location.y),
1051
- node_id: UInt32.from(nodeId),
1070
+ castballot(player: NameType, ballotId: UInt64Type, picks: number[]): Action {
1071
+ return this.server.action('castballot', {
1072
+ player,
1073
+ ballot_id: UInt64.from(ballotId),
1074
+ picks: picks.map((pick) => UInt32.from(pick)),
1052
1075
  })
1053
1076
  }
1054
1077
 
1055
- voteready(maxBallots: UInt32Type = UInt32.from(0)): Action {
1056
- return this.server.action('voteready', {
1057
- max_ballots: UInt32.from(maxBallots),
1078
+ settleballot(ballotId: UInt64Type, maxPages: UInt32Type = UInt32.from(0)): Action {
1079
+ return this.server.action('settleballot', {
1080
+ ballot_id: UInt64.from(ballotId),
1081
+ max_pages: UInt32.from(maxPages),
1058
1082
  })
1059
1083
  }
1084
+
1085
+ voteready(maxPages: UInt32Type = UInt32.from(0)): Action {
1086
+ return this.server.action('voteready', {max_pages: UInt32.from(maxPages)})
1087
+ }
1060
1088
  }
@@ -15,6 +15,10 @@ export abstract class BaseManager {
15
15
  return this.context.platform
16
16
  }
17
17
 
18
+ protected get fund() {
19
+ return this.context.fund
20
+ }
21
+
18
22
  protected get atomicAssetsAccount() {
19
23
  return this.context.atomicAssetsAccount
20
24
  }
@@ -1,6 +1,7 @@
1
1
  import type {APIClient} from '@wharfkit/antelope'
2
2
  import type {Contract} from '@wharfkit/contract'
3
3
  import type {PlatformContract} from '../contracts'
4
+ import {FundContract} from '../contracts'
4
5
  import {GameState} from '../entities/gamestate'
5
6
 
6
7
  import {EntitiesManager} from './entities'
@@ -38,7 +39,8 @@ export class GameContext {
38
39
  public readonly client: APIClient,
39
40
  public readonly server: Contract,
40
41
  public readonly platform: Contract,
41
- public readonly atomicAssetsAccount: string = 'atomicassets'
42
+ public readonly atomicAssetsAccount: string = 'atomicassets',
43
+ public readonly fund: Contract = new FundContract.Contract({client})
42
44
  ) {}
43
45
 
44
46
  get entities(): EntitiesManager {
@@ -23,8 +23,10 @@ export type {
23
23
  FoundedWorld,
24
24
  FoundedWorldRef,
25
25
  InfluenceStanding,
26
- PendingBallot,
27
- VoteCast,
26
+ Ballot,
27
+ BallotVote,
28
+ NodeProgress,
29
+ QueuedSeat,
28
30
  VoteOption,
29
31
  VoteStandings,
30
32
  } from './influence'
@@ -16,43 +16,41 @@ function managerWith(rowsByTable: Record<string, unknown[]>) {
16
16
  }
17
17
 
18
18
  describe('InfluenceManager scoped table reads', () => {
19
- it('getVoteCasts scopes infvote by location and maps fields', async () => {
19
+ it('getBallotVotes scopes ballotpicks by ballot id and maps fields', async () => {
20
20
  const {manager, calls} = managerWith({
21
- infvote: [{account: Name.from('eggmaple.gm'), epoch: 5, node_id: 2, weight: '100'}],
21
+ ballotpicks: [{account: Name.from('eggmaple.gm'), picks: [2, 1]}],
22
22
  })
23
- const rows = await manager.getVoteCasts(LOCATION)
23
+ const rows = await manager.getBallotVotes(7n)
24
24
  expect(calls).toHaveLength(1)
25
- expect(calls[0].table).toBe('infvote')
26
- expect(UInt64.from(calls[0].scope as never).equals(coordsToLocationId(LOCATION))).toBe(true)
27
- expect(rows).toEqual([
28
- {account: Name.from('eggmaple.gm'), epoch: 5, nodeId: 2, weight: 100n},
29
- ])
25
+ expect(calls[0].table).toBe('ballotpicks')
26
+ expect(UInt64.from(calls[0].scope as never).equals(UInt64.from(7))).toBe(true)
27
+ expect(rows).toEqual([{account: Name.from('eggmaple.gm'), picks: [2, 1]}])
30
28
  })
31
29
 
32
- it('getVoteTallies scopes inftally by location and maps fields', async () => {
30
+ it('getBuiltCharters scopes mandates by location and maps fields', async () => {
33
31
  const {manager, calls} = managerWith({
34
- inftally: [{node_id: 3, total: '250'}],
32
+ mandates: [{node_id: 1, repeats: 2}],
35
33
  })
36
- const rows = await manager.getVoteTallies(LOCATION)
37
- expect(calls[0].table).toBe('inftally')
34
+ const rows = await manager.getBuiltCharters(LOCATION)
35
+ expect(calls[0].table).toBe('mandates')
38
36
  expect(UInt64.from(calls[0].scope as never).equals(coordsToLocationId(LOCATION))).toBe(true)
39
- expect(rows).toEqual([{nodeId: 3, total: 250n}])
37
+ expect(rows).toEqual([{nodeId: 1, repeats: 2}])
40
38
  })
41
39
 
42
- it('getBuiltCharters scopes charters by location and maps fields', async () => {
40
+ it('getBuildings scopes buildings by location and maps fields', async () => {
43
41
  const {manager, calls} = managerWith({
44
- charters: [{node_id: 1, entity_id: '9001'}],
42
+ buildings: [{entity_id: '9001', building: 3}],
45
43
  })
46
- const rows = await manager.getBuiltCharters(LOCATION)
47
- expect(calls[0].table).toBe('charters')
44
+ const rows = await manager.getBuildings(LOCATION)
45
+ expect(calls[0].table).toBe('buildings')
48
46
  expect(UInt64.from(calls[0].scope as never).equals(coordsToLocationId(LOCATION))).toBe(true)
49
- expect(rows).toEqual([{nodeId: 1, entityId: 9001n}])
47
+ expect(rows).toEqual([{entityId: 9001n, building: 3}])
50
48
  })
51
49
 
52
50
  it('returns an empty array when the scope has no rows', async () => {
53
51
  const {manager} = managerWith({})
54
- expect(await manager.getVoteCasts(LOCATION)).toEqual([])
55
- expect(await manager.getVoteTallies(LOCATION)).toEqual([])
52
+ expect(await manager.getBallotVotes(7n)).toEqual([])
56
53
  expect(await manager.getBuiltCharters(LOCATION)).toEqual([])
54
+ expect(await manager.getBuildings(LOCATION)).toEqual([])
57
55
  })
58
56
  })