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

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 (85) hide show
  1. package/lib/shipload.d.ts +786 -321
  2. package/lib/shipload.js +2731 -1305
  3. package/lib/shipload.js.map +1 -1
  4. package/lib/shipload.m.js +2644 -1286
  5. package/lib/shipload.m.js.map +1 -1
  6. package/lib/testing.d.ts +223 -146
  7. package/lib/testing.js +907 -563
  8. package/lib/testing.js.map +1 -1
  9. package/lib/testing.m.js +907 -563
  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 +521 -330
  20. package/src/data/charters.json +325 -127
  21. package/src/data/entities.json +29 -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/metadata.ts +9 -2
  26. package/src/data/recipes.json +56 -95
  27. package/src/derivation/build-methods.test.ts +59 -1
  28. package/src/derivation/build-methods.ts +2 -0
  29. package/src/derivation/capabilities.ts +7 -7
  30. package/src/derivation/strata.ts +5 -3
  31. package/src/derivation/tiers.ts +5 -5
  32. package/src/entity/hydrate.test.ts +156 -0
  33. package/src/entity/hydrate.ts +86 -0
  34. package/src/errors.ts +9 -0
  35. package/src/format.ts +15 -13
  36. package/src/index-module.ts +32 -5
  37. package/src/influence/ballot.test.ts +103 -0
  38. package/src/influence/ballot.ts +98 -0
  39. package/src/influence/charter-metadata.test.ts +136 -0
  40. package/src/influence/charter-metadata.ts +236 -0
  41. package/src/influence/charters.test.ts +51 -65
  42. package/src/influence/charters.ts +70 -40
  43. package/src/influence/civic-shuttle.test.ts +159 -0
  44. package/src/influence/civic-shuttle.ts +115 -0
  45. package/src/influence/civic.test.ts +287 -0
  46. package/src/influence/civic.ts +269 -0
  47. package/src/influence/constants.ts +30 -9
  48. package/src/influence/decomp.ts +15 -15
  49. package/src/influence/duration.ts +42 -6
  50. package/src/influence/index.ts +59 -6
  51. package/src/influence/influence.test.ts +76 -9
  52. package/src/influence/valuation.ts +17 -17
  53. package/src/managers/actions.ts +99 -37
  54. package/src/managers/base.ts +4 -0
  55. package/src/managers/context.ts +3 -1
  56. package/src/managers/epochs.ts +32 -1
  57. package/src/managers/index.ts +4 -2
  58. package/src/managers/influence.test.ts +18 -20
  59. package/src/managers/influence.ts +137 -84
  60. package/src/managers/jobs.test.ts +2 -2
  61. package/src/managers/jobs.ts +4 -4
  62. package/src/nft/description.ts +10 -11
  63. package/src/planner/index.ts +54 -0
  64. package/src/planner/planner.test.ts +127 -2
  65. package/src/resolution/display-name.ts +1 -1
  66. package/src/scheduling/availability.test.ts +113 -0
  67. package/src/scheduling/availability.ts +48 -8
  68. package/src/scheduling/epoch.ts +1 -0
  69. package/src/scheduling/jobs.ts +1 -1
  70. package/src/scheduling/projection.ts +2 -16
  71. package/src/scheduling/task-cargo.test.ts +62 -1
  72. package/src/scheduling/task-cargo.ts +25 -10
  73. package/src/scheduling/task-effects.test.ts +35 -0
  74. package/src/scheduling/task-effects.ts +34 -0
  75. package/src/scheduling/unwrap.test.ts +3 -3
  76. package/src/scheduling/unwrap.ts +3 -3
  77. package/src/shipload.ts +22 -3
  78. package/src/travel/reach.test.ts +86 -0
  79. package/src/travel/reach.ts +23 -10
  80. package/src/travel/route-build.test.ts +63 -0
  81. package/src/travel/route-build.ts +60 -0
  82. package/src/travel/travel.ts +2 -1
  83. package/src/types.ts +6 -2
  84. package/src/utils/hash.ts +18 -2
  85. package/src/utils/system.ts +6 -1
@@ -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 {
@@ -358,6 +366,28 @@ export class ActionsManager extends BaseManager {
358
366
  })
359
367
  }
360
368
 
369
+ civicshuttle(
370
+ buildingId: UInt64Type,
371
+ fromId: UInt64Type,
372
+ toId: UInt64Type,
373
+ items: ServerContract.ActionParams.Type.cargo_item[]
374
+ ): Action {
375
+ return this.server.action('civicshuttle', {
376
+ building: UInt64.from(buildingId),
377
+ from_id: UInt64.from(fromId),
378
+ to_id: UInt64.from(toId),
379
+ items,
380
+ })
381
+ }
382
+
383
+ cancelcivic(buildingId: UInt64Type, laneKey: UInt8Type, fromId: UInt64Type): Action {
384
+ return this.server.action('cancelcivic', {
385
+ building: UInt64.from(buildingId),
386
+ lane_key: UInt8.from(laneKey),
387
+ from_id: UInt64.from(fromId),
388
+ })
389
+ }
390
+
361
391
  launch(
362
392
  launcherId: UInt64Type,
363
393
  catcherId: UInt64Type,
@@ -524,58 +554,51 @@ export class ActionsManager extends BaseManager {
524
554
  return this.server.action('clustercraft', params)
525
555
  }
526
556
 
527
- claimjob(jobId: UInt64Type, shipId: UInt64Type): Action {
528
- const params: ServerContract.ActionParams.claimjob = {
557
+ claimcraft(jobId: UInt64Type, shipId: UInt64Type): Action {
558
+ const params: ServerContract.ActionParams.claimcraft = {
529
559
  job_id: UInt64.from(jobId),
530
560
  ship_id: UInt64.from(shipId),
531
561
  }
532
- return this.server.action('claimjob', params)
562
+ return this.server.action('claimcraft', params)
533
563
  }
534
564
 
535
- canceljob(jobId: UInt64Type, shipId: UInt64Type): Action {
536
- const params: ServerContract.ActionParams.canceljob = {
565
+ cancelcraft(jobId: UInt64Type, shipId: UInt64Type): Action {
566
+ const params: ServerContract.ActionParams.cancelcraft = {
537
567
  job_id: UInt64.from(jobId),
538
568
  ship_id: UInt64.from(shipId),
539
569
  }
540
- return this.server.action('canceljob', params)
570
+ return this.server.action('cancelcraft', params)
541
571
  }
542
572
 
543
- upgradejob(
573
+ buildjob(
544
574
  targetId: UInt64Type,
545
575
  dockId: UInt64Type,
576
+ slot: UInt8Type,
546
577
  targetItemId: UInt16Type,
547
578
  inputs: ServerContract.ActionParams.Type.cargo_item[]
548
579
  ): Action {
549
- const params: ServerContract.ActionParams.upgradejob = {
580
+ const params: ServerContract.ActionParams.buildjob = {
550
581
  target_id: UInt64.from(targetId),
551
582
  dock_id: UInt64.from(dockId),
583
+ slot: UInt8.from(slot),
552
584
  target_item_id: UInt16.from(targetItemId),
553
585
  inputs,
554
586
  }
555
- return this.server.action('upgradejob', params)
587
+ return this.server.action('buildjob', params)
556
588
  }
557
589
 
558
- claimupgrade(jobId: UInt64Type): Action {
559
- const params: ServerContract.ActionParams.claimupgrade = {
590
+ claimbuild(jobId: UInt64Type): Action {
591
+ const params: ServerContract.ActionParams.claimbuild = {
560
592
  job_id: UInt64.from(jobId),
561
593
  }
562
- return this.server.action('claimupgrade', params)
594
+ return this.server.action('claimbuild', params)
563
595
  }
564
596
 
565
- cancelupgrade(jobId: UInt64Type): Action {
566
- const params: ServerContract.ActionParams.cancelupgrade = {
597
+ cancelbuild(jobId: UInt64Type): Action {
598
+ const params: ServerContract.ActionParams.cancelbuild = {
567
599
  job_id: UInt64.from(jobId),
568
600
  }
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)
601
+ return this.server.action('cancelbuild', params)
579
602
  }
580
603
 
581
604
  blend(entityId: UInt64Type, inputs: ServerContract.ActionParams.Type.cargo_item[]): Action {
@@ -844,6 +867,12 @@ export class ActionsManager extends BaseManager {
844
867
  return actions
845
868
  }
846
869
 
870
+ setunwrapmin(assetId: UInt64Type): Action {
871
+ return this.server.action('setunwrapmin', {
872
+ asset_id: UInt64.from(assetId),
873
+ })
874
+ }
875
+
847
876
  placecargo(owner: NameType, hostId: UInt64Type, assetId: UInt64Type): Action {
848
877
  return this.server.action('placecargo', {
849
878
  owner: Name.from(owner),
@@ -975,6 +1004,18 @@ export class ActionsManager extends BaseManager {
975
1004
  })
976
1005
  }
977
1006
 
1007
+ setdeadline(deadline: UInt32Type): Action {
1008
+ return this.server.action('setdeadline', {
1009
+ deadline: UInt32.from(deadline),
1010
+ })
1011
+ }
1012
+
1013
+ closeepoch(epoch: UInt64Type): Action {
1014
+ return this.server.action('closeepoch', {
1015
+ epoch: UInt64.from(epoch),
1016
+ })
1017
+ }
1018
+
978
1019
  cleanrsvp(epoch: UInt64Type, maxRows: UInt64Type): Action {
979
1020
  return this.server.action('cleanrsvp', {
980
1021
  epoch: UInt64.from(epoch),
@@ -982,6 +1023,23 @@ export class ActionsManager extends BaseManager {
982
1023
  })
983
1024
  }
984
1025
 
1026
+ addFundToken(tokenContract: NameType, tokenSymbol: Asset.SymbolType): Action {
1027
+ return this.fund.action('addtoken', {
1028
+ token_contract: Name.from(tokenContract),
1029
+ token_symbol: Asset.Symbol.from(tokenSymbol),
1030
+ })
1031
+ }
1032
+
1033
+ removeFundToken(tokenContract: NameType): Action {
1034
+ return this.fund.action('deltoken', {
1035
+ token_contract: Name.from(tokenContract),
1036
+ })
1037
+ }
1038
+
1039
+ collectFund(): Action {
1040
+ return this.fund.action('collect', {})
1041
+ }
1042
+
985
1043
  found(player: NameType, entityId: UInt64Type, location: CoordinatesType): Action {
986
1044
  return this.server.action('found', {
987
1045
  player: Name.from(player),
@@ -1043,18 +1101,22 @@ export class ActionsManager extends BaseManager {
1043
1101
  })
1044
1102
  }
1045
1103
 
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),
1104
+ castballot(player: NameType, ballotId: UInt64Type, picks: number[]): Action {
1105
+ return this.server.action('castballot', {
1106
+ player,
1107
+ ballot_id: UInt64.from(ballotId),
1108
+ picks: picks.map((pick) => UInt32.from(pick)),
1052
1109
  })
1053
1110
  }
1054
1111
 
1055
- voteready(maxBallots: UInt32Type = UInt32.from(0)): Action {
1056
- return this.server.action('voteready', {
1057
- max_ballots: UInt32.from(maxBallots),
1112
+ settleballot(ballotId: UInt64Type, maxPages: UInt32Type = UInt32.from(0)): Action {
1113
+ return this.server.action('settleballot', {
1114
+ ballot_id: UInt64.from(ballotId),
1115
+ max_pages: UInt32.from(maxPages),
1058
1116
  })
1059
1117
  }
1118
+
1119
+ voteready(maxPages: UInt32Type = UInt32.from(0)): Action {
1120
+ return this.server.action('voteready', {max_pages: UInt32.from(maxPages)})
1121
+ }
1060
1122
  }
@@ -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 {
@@ -1,8 +1,17 @@
1
- import {UInt64, type UInt64Type} from '@wharfkit/antelope'
1
+ import {Checksum256, UInt64, type UInt64Type} from '@wharfkit/antelope'
2
2
  import {BaseManager} from './base'
3
3
  import {type EpochInfo, getCurrentEpoch, getEpochInfo} from '../scheduling/epoch'
4
4
  import type {ServerContract} from '../contracts'
5
5
 
6
+ export const DEFAULT_EPOCH_DEADLINE = 10800
7
+
8
+ const EMPTY_SEED = Checksum256.from('0'.repeat(64))
9
+
10
+ export interface EpochQuorumState {
11
+ threshold: number
12
+ finalized: boolean
13
+ }
14
+
6
15
  export class EpochsManager extends BaseManager {
7
16
  async getCurrentHeight(): Promise<UInt64> {
8
17
  const game = await this.getGame()
@@ -56,6 +65,12 @@ export class EpochsManager extends BaseManager {
56
65
  return this.server.table('epoch').get(target)
57
66
  }
58
67
 
68
+ async getEpochState(epoch: UInt64Type): Promise<EpochQuorumState> {
69
+ const row = await this.getEpochRow(epoch)
70
+ if (!row) return {threshold: 0, finalized: false}
71
+ return {threshold: Number(row.threshold), finalized: !row.seed.equals(EMPTY_SEED)}
72
+ }
73
+
59
74
  async getActiveEpochInfo(): Promise<ServerContract.Types.epoch_row | undefined> {
60
75
  const rows = await this.server.table('epoch').all()
61
76
  if (rows.length === 0) {
@@ -73,6 +88,22 @@ export class EpochsManager extends BaseManager {
73
88
  return cfg ? Number(cfg.threshold) : 0
74
89
  }
75
90
 
91
+ async getDeadline(): Promise<number> {
92
+ const cfg = await this.server.table('oraclecfg').get()
93
+ return cfg ? Number(cfg.deadline) : DEFAULT_EPOCH_DEADLINE
94
+ }
95
+
96
+ async getCloseDueAt(epoch: UInt64Type): Promise<Date> {
97
+ const info = await this.getByHeight(epoch)
98
+ const deadline = await this.getDeadline()
99
+ return new Date(info.start.getTime() + deadline * 1000)
100
+ }
101
+
102
+ async getSecondsUntilClose(epoch: UInt64Type): Promise<number> {
103
+ const dueAt = await this.getCloseDueAt(epoch)
104
+ return Math.ceil((dueAt.getTime() - Date.now()) / 1000)
105
+ }
106
+
76
107
  async getCommitsFor(epoch: UInt64Type): Promise<ServerContract.Types.commit_row[]> {
77
108
  const target = UInt64.from(epoch)
78
109
  const rows = await this.server.table('commit').all()
@@ -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
  })