@shipload/sdk 1.0.0-next.72 → 1.0.0-next.74
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 +576 -133
- package/lib/shipload.js +6019 -5114
- package/lib/shipload.js.map +1 -1
- package/lib/shipload.m.js +6002 -5108
- package/lib/shipload.m.js.map +1 -1
- package/lib/testing.d.ts +194 -52
- package/lib/testing.js +767 -468
- package/lib/testing.js.map +1 -1
- package/lib/testing.m.js +767 -468
- package/lib/testing.m.js.map +1 -1
- package/package.json +1 -1
- package/src/contracts/server.ts +523 -143
- package/src/data/catalog.test.ts +81 -1
- package/src/data/catalog.ts +6 -4
- package/src/data/entities.json +2 -2
- package/src/data/metadata.ts +197 -363
- package/src/data/task-types.json +184 -0
- package/src/entities/makers.ts +2 -2
- package/src/index-module.ts +31 -2
- package/src/influence/civic-shuttle.test.ts +58 -0
- package/src/influence/civic-shuttle.ts +52 -6
- package/src/influence/duration.ts +0 -65
- package/src/influence/index.ts +4 -5
- package/src/influence/influence.test.ts +51 -136
- package/src/influence/valuation.ts +75 -0
- package/src/managers/actions.ts +49 -10
- package/src/managers/balances.test.ts +33 -0
- package/src/managers/balances.ts +15 -0
- package/src/managers/context.ts +50 -11
- package/src/managers/index.ts +14 -0
- package/src/managers/jobs.test.ts +82 -1
- package/src/managers/jobs.ts +41 -2
- package/src/managers/nft.test.ts +173 -1
- package/src/managers/nft.ts +35 -2
- package/src/managers/shuttle.test.ts +562 -0
- package/src/managers/shuttle.ts +397 -0
- package/src/resolution/resolve-item.ts +2 -2
- package/src/scheduling/availability.ts +10 -0
- package/src/scheduling/energy.ts +55 -1
- package/src/scheduling/jobs.test.ts +171 -1
- package/src/scheduling/jobs.ts +110 -13
- package/src/scheduling/projection.ts +2 -1
- package/src/scheduling/task-effects.ts +38 -0
- package/src/scheduling/unwrap.test.ts +60 -0
- package/src/scheduling/unwrap.ts +24 -8
- package/src/shipload.ts +23 -4
- package/src/types.ts +1 -0
|
@@ -41,7 +41,7 @@ describe('JobsManager.getOwnedJobs', () => {
|
|
|
41
41
|
expect(jobs[0].inputs).toEqual([{item: 'in'}] as never)
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
it('reports
|
|
44
|
+
it('reports a legacy undeposited row (inputs only) as dropping off, whatever its window says', async () => {
|
|
45
45
|
const inFlight = row({
|
|
46
46
|
deposited: false,
|
|
47
47
|
cargo: [{item: 'in'}],
|
|
@@ -57,6 +57,27 @@ describe('JobsManager.getOwnedJobs', () => {
|
|
|
57
57
|
expect(jobs[0].inputs).toEqual([{item: 'in'}] as never)
|
|
58
58
|
})
|
|
59
59
|
|
|
60
|
+
it('reads a booking-time undeposited row whose input is booked as more than one stack', async () => {
|
|
61
|
+
const inFlight = row({
|
|
62
|
+
deposited: false,
|
|
63
|
+
cargo: [
|
|
64
|
+
{item_id: 101, quantity: 20},
|
|
65
|
+
{item_id: 101, quantity: 30},
|
|
66
|
+
],
|
|
67
|
+
})
|
|
68
|
+
const m = managerWith(
|
|
69
|
+
async () => [inFlight],
|
|
70
|
+
async () => []
|
|
71
|
+
)
|
|
72
|
+
const jobs = await m.getOwnedJobs(OWNER, {now: new Date('2026-07-26T11:30:00Z')})
|
|
73
|
+
expect(jobs[0].status).toBe('dropping')
|
|
74
|
+
expect(jobs[0].inputs).toEqual([
|
|
75
|
+
{item_id: 101, quantity: 20},
|
|
76
|
+
{item_id: 101, quantity: 30},
|
|
77
|
+
] as never)
|
|
78
|
+
expect(jobs[0].output).toBeNull()
|
|
79
|
+
})
|
|
80
|
+
|
|
60
81
|
it('reports a cancelled row as ready with its inputs held', async () => {
|
|
61
82
|
const cancelled = row({
|
|
62
83
|
quantity: {toNumber: () => 0},
|
|
@@ -94,3 +115,63 @@ describe('JobsManager.getOwnedJobs', () => {
|
|
|
94
115
|
expect(jobs).toHaveLength(1)
|
|
95
116
|
})
|
|
96
117
|
})
|
|
118
|
+
|
|
119
|
+
const buildRow = (over: Record<string, unknown> = {}) => ({
|
|
120
|
+
id: {toNumber: () => 9},
|
|
121
|
+
building: {toNumber: () => 2},
|
|
122
|
+
socket: {toNumber: () => 1},
|
|
123
|
+
target: {toNumber: () => 5},
|
|
124
|
+
owner: Name.from(OWNER),
|
|
125
|
+
coords: {x: {toNumber: () => 0}, y: {toNumber: () => 0}},
|
|
126
|
+
starts_at: {toDate: () => new Date('2026-07-26T10:00:00Z')},
|
|
127
|
+
completes_at: {toDate: () => new Date('2026-07-26T11:00:00Z')},
|
|
128
|
+
arrives_at: {toDate: () => new Date('2026-07-26T09:45:00Z')},
|
|
129
|
+
target_item_id: {toNumber: () => 10212},
|
|
130
|
+
cargo: [{item: 'in'}],
|
|
131
|
+
deposited: true,
|
|
132
|
+
...over,
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
function managerWithReadonly(impl: (name: string, data: unknown) => Promise<unknown>) {
|
|
136
|
+
const ctx = {server: {readonly: impl}} as never
|
|
137
|
+
return new JobsManager(ctx)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
describe('JobsManager.getBuildJobs', () => {
|
|
141
|
+
it('reads the dock queue through getbuildjobs and parses every row', async () => {
|
|
142
|
+
let called: unknown = null
|
|
143
|
+
const m = managerWithReadonly(async (name, data) => {
|
|
144
|
+
called = {name, data}
|
|
145
|
+
return {jobs: [buildRow(), buildRow({id: {toNumber: () => 10}, deposited: false})]}
|
|
146
|
+
})
|
|
147
|
+
const jobs = await m.getBuildJobs(2, {now: new Date('2026-07-26T11:30:00Z')})
|
|
148
|
+
expect(called).toMatchObject({name: 'getbuildjobs'})
|
|
149
|
+
expect(String((called as {data: {building_id: unknown}}).data.building_id)).toBe('2')
|
|
150
|
+
expect(jobs).toHaveLength(2)
|
|
151
|
+
expect(jobs[0]).toMatchObject({
|
|
152
|
+
id: 9,
|
|
153
|
+
building: 2,
|
|
154
|
+
socket: 1,
|
|
155
|
+
targetId: 5,
|
|
156
|
+
owner: OWNER,
|
|
157
|
+
targetItemId: 10212,
|
|
158
|
+
deposited: true,
|
|
159
|
+
status: 'ready',
|
|
160
|
+
})
|
|
161
|
+
expect(jobs[0].coords).toEqual({x: 0, y: 0})
|
|
162
|
+
expect(jobs[0].arrivesAt).toEqual(new Date('2026-07-26T09:45:00Z'))
|
|
163
|
+
expect(jobs[0].inputs).toEqual([{item: 'in'}] as never)
|
|
164
|
+
expect(jobs[1].status).toBe('dropping')
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('reports a booked row before its window as queued', async () => {
|
|
168
|
+
const m = managerWithReadonly(async () => ({jobs: [buildRow()]}))
|
|
169
|
+
const jobs = await m.getBuildJobs(2, {now: new Date('2026-07-26T09:50:00Z')})
|
|
170
|
+
expect(jobs[0].status).toBe('queued')
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
it('returns an empty list when the result carries no jobs', async () => {
|
|
174
|
+
const m = managerWithReadonly(async () => ({}))
|
|
175
|
+
expect(await m.getBuildJobs(2)).toEqual([])
|
|
176
|
+
})
|
|
177
|
+
})
|
package/src/managers/jobs.ts
CHANGED
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import {Name, type NameType} from '@wharfkit/antelope'
|
|
1
|
+
import {Name, UInt64, type NameType, type UInt64Type} from '@wharfkit/antelope'
|
|
2
2
|
import {BaseManager} from './base'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
jobDeposited,
|
|
5
|
+
jobStatus,
|
|
6
|
+
splitJobCargo,
|
|
7
|
+
type BuildJob,
|
|
8
|
+
type OwnedJob,
|
|
9
|
+
} from '../scheduling/jobs'
|
|
4
10
|
import type {ServerContract} from '../contracts'
|
|
5
11
|
|
|
6
12
|
type JobRow = ServerContract.Types.craftjob_row
|
|
13
|
+
type BuildJobRow = ServerContract.Types.buildjob_row
|
|
7
14
|
|
|
8
15
|
export class JobsManager extends BaseManager {
|
|
9
16
|
async getOwnedJobs(owner: NameType, opts?: {now?: Date}): Promise<OwnedJob[]> {
|
|
@@ -29,6 +36,38 @@ export class JobsManager extends BaseManager {
|
|
|
29
36
|
return rows.filter((r) => ownerName.equals(r.owner)).map((r) => this.parseOwnedJob(r, now))
|
|
30
37
|
}
|
|
31
38
|
|
|
39
|
+
async getBuildJobs(dockId: UInt64Type, opts?: {now?: Date}): Promise<BuildJob[]> {
|
|
40
|
+
const now = opts?.now ?? new Date()
|
|
41
|
+
const result = (await this.server.readonly('getbuildjobs', {
|
|
42
|
+
building_id: UInt64.from(dockId),
|
|
43
|
+
})) as ServerContract.Types.buildjobs_result | undefined
|
|
44
|
+
return (result?.jobs ?? []).map((r) => this.parseBuildJob(r, now))
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
private parseBuildJob(r: BuildJobRow, now: Date): BuildJob {
|
|
48
|
+
const startsAt = r.starts_at.toDate()
|
|
49
|
+
const completesAt = r.completes_at.toDate()
|
|
50
|
+
const arrivesAt = r.arrives_at.toDate()
|
|
51
|
+
const deposited = jobDeposited(r.deposited)
|
|
52
|
+
const building = r.building.toNumber()
|
|
53
|
+
const inputs = [...r.cargo]
|
|
54
|
+
return {
|
|
55
|
+
id: r.id.toNumber(),
|
|
56
|
+
building,
|
|
57
|
+
socket: r.socket.toNumber(),
|
|
58
|
+
targetId: r.target.toNumber(),
|
|
59
|
+
owner: r.owner.toString(),
|
|
60
|
+
coords: {x: r.coords.x.toNumber(), y: r.coords.y.toNumber()},
|
|
61
|
+
startsAt,
|
|
62
|
+
completesAt,
|
|
63
|
+
arrivesAt,
|
|
64
|
+
targetItemId: r.target_item_id.toNumber(),
|
|
65
|
+
status: jobStatus({startsAt, completesAt, arrivesAt, deposited, building, inputs}, now),
|
|
66
|
+
deposited,
|
|
67
|
+
inputs,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
32
71
|
private parseOwnedJob(r: JobRow, now: Date): OwnedJob {
|
|
33
72
|
const startsAt = r.starts_at.toDate()
|
|
34
73
|
const completesAt = r.completes_at.toDate()
|
package/src/managers/nft.test.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import {describe, expect, test} from 'bun:test'
|
|
2
|
-
import {
|
|
2
|
+
import {Asset, Name} from '@wharfkit/antelope'
|
|
3
|
+
import {NftManager, resolveLockedAmount, wrapCostKey} from './nft'
|
|
4
|
+
import type {GameContext} from './context'
|
|
5
|
+
import {ServerContract} from '../contracts'
|
|
3
6
|
|
|
4
7
|
describe('resolveLockedAmount', () => {
|
|
5
8
|
test('no fee refunds the full cost', () => {
|
|
@@ -19,3 +22,172 @@ describe('wrapCostKey', () => {
|
|
|
19
22
|
expect(wrapCostKey(3, 2).toString()).toBe('770')
|
|
20
23
|
})
|
|
21
24
|
})
|
|
25
|
+
|
|
26
|
+
interface StubOptions {
|
|
27
|
+
wrapConfig?: {fee_pct: number; fee_account: string; min_asset_id?: number} | null
|
|
28
|
+
wrapCosts?: {item_type: number; tier: number; amount: number}[]
|
|
29
|
+
depositConfig?: {tokenContract: string; symbol: string} | null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function stubContext(options: StubOptions = {}) {
|
|
33
|
+
const counts = {wrapconfig: 0, wrapcost: 0, depositcfg: 0}
|
|
34
|
+
const costRows = (options.wrapCosts ?? []).map((row) =>
|
|
35
|
+
ServerContract.Types.wrapcost_row.from(row)
|
|
36
|
+
)
|
|
37
|
+
const server = {
|
|
38
|
+
table(name: string) {
|
|
39
|
+
if (name === 'wrapconfig') {
|
|
40
|
+
return {
|
|
41
|
+
get: async () => {
|
|
42
|
+
counts.wrapconfig++
|
|
43
|
+
return options.wrapConfig
|
|
44
|
+
? ServerContract.Types.wrapconfig_row.from({
|
|
45
|
+
...options.wrapConfig,
|
|
46
|
+
min_asset_id: options.wrapConfig.min_asset_id ?? 0,
|
|
47
|
+
})
|
|
48
|
+
: undefined
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (name === 'wrapcost') {
|
|
53
|
+
return {
|
|
54
|
+
get: async (key: {toString(): string}) => {
|
|
55
|
+
counts.wrapcost++
|
|
56
|
+
return costRows.find(
|
|
57
|
+
(row) =>
|
|
58
|
+
wrapCostKey(Number(row.item_type), Number(row.tier)).toString() ===
|
|
59
|
+
key.toString()
|
|
60
|
+
)
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
throw new Error(`unexpected table: ${name}`)
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
const balances = {
|
|
68
|
+
getDepositConfig: async () => {
|
|
69
|
+
counts.depositcfg++
|
|
70
|
+
return options.depositConfig
|
|
71
|
+
? {
|
|
72
|
+
tokenContract: Name.from(options.depositConfig.tokenContract),
|
|
73
|
+
symbol: Asset.Symbol.from(options.depositConfig.symbol),
|
|
74
|
+
}
|
|
75
|
+
: null
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
const context = {server, balances} as unknown as GameContext
|
|
79
|
+
return {manager: new NftManager(context), counts}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const DEPOSIT = {tokenContract: 'scrap.gm', symbol: '0,SCRAP'}
|
|
83
|
+
|
|
84
|
+
describe('setWrapConfig', () => {
|
|
85
|
+
test('a seeded config keeps getWrapConfig off the chain', async () => {
|
|
86
|
+
const {manager, counts} = stubContext({wrapConfig: {fee_pct: 200, fee_account: 'fee.gm'}})
|
|
87
|
+
manager.setWrapConfig({feePctBasisPoints: 200, feeAccount: 'fee.gm'})
|
|
88
|
+
|
|
89
|
+
const config = await manager.getWrapConfig()
|
|
90
|
+
expect(config?.feePctBasisPoints).toBe(200)
|
|
91
|
+
expect(String(config?.feeAccount)).toBe('fee.gm')
|
|
92
|
+
expect(counts.wrapconfig).toBe(0)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('a reload still reaches the chain', async () => {
|
|
96
|
+
const {manager, counts} = stubContext({wrapConfig: {fee_pct: 200, fee_account: 'fee.gm'}})
|
|
97
|
+
manager.setWrapConfig({feePctBasisPoints: 200, feeAccount: 'fee.gm'})
|
|
98
|
+
await manager.getWrapConfig(true)
|
|
99
|
+
expect(counts.wrapconfig).toBe(1)
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
test('seeding null records a chain with no wrap fee configured', async () => {
|
|
103
|
+
const {manager, counts} = stubContext({wrapConfig: {fee_pct: 200, fee_account: 'fee.gm'}})
|
|
104
|
+
manager.setWrapConfig(null)
|
|
105
|
+
expect(await manager.getWrapConfig()).toBeNull()
|
|
106
|
+
expect(counts.wrapconfig).toBe(0)
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
describe('setWrapCosts', () => {
|
|
111
|
+
test('a seeded cost keeps getWrapCost off the chain', async () => {
|
|
112
|
+
const {manager, counts} = stubContext({
|
|
113
|
+
wrapCosts: [{item_type: 3, tier: 2, amount: 500}],
|
|
114
|
+
})
|
|
115
|
+
manager.setWrapCosts([{itemType: 3, tier: 2, units: 500n}])
|
|
116
|
+
|
|
117
|
+
expect(await manager.getWrapCost(3, 2)).toBe(500n)
|
|
118
|
+
expect(counts.wrapcost).toBe(0)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
test('an item missing from the seed falls back to chain', async () => {
|
|
122
|
+
const {manager, counts} = stubContext({
|
|
123
|
+
wrapCosts: [{item_type: 3, tier: 2, amount: 500}],
|
|
124
|
+
})
|
|
125
|
+
manager.setWrapCosts([{itemType: 3, tier: 2, units: 500n}])
|
|
126
|
+
|
|
127
|
+
expect(await manager.getWrapCost(9, 1)).toBe(0n)
|
|
128
|
+
expect(counts.wrapcost).toBe(1)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
test('a reload still reaches the chain', async () => {
|
|
132
|
+
const {manager, counts} = stubContext({
|
|
133
|
+
wrapCosts: [{item_type: 3, tier: 2, amount: 500}],
|
|
134
|
+
})
|
|
135
|
+
manager.setWrapCosts([{itemType: 3, tier: 2, units: 500n}])
|
|
136
|
+
await manager.getWrapCost(3, 2, true)
|
|
137
|
+
expect(counts.wrapcost).toBe(1)
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
describe('getWrapDeposit', () => {
|
|
142
|
+
test('with every seed present, makes no chain reads', async () => {
|
|
143
|
+
const {manager, counts} = stubContext({
|
|
144
|
+
wrapCosts: [{item_type: 3, tier: 2, amount: 500}],
|
|
145
|
+
wrapConfig: {fee_pct: 200, fee_account: 'fee.gm'},
|
|
146
|
+
depositConfig: DEPOSIT,
|
|
147
|
+
})
|
|
148
|
+
manager.setWrapCosts([{itemType: 3, tier: 2, units: 500n}])
|
|
149
|
+
manager.setWrapConfig({feePctBasisPoints: 200, feeAccount: 'fee.gm'})
|
|
150
|
+
|
|
151
|
+
const deposit = await manager.getWrapDeposit(3, 2)
|
|
152
|
+
expect(deposit).toEqual({
|
|
153
|
+
cost: 500n,
|
|
154
|
+
refund: 490n,
|
|
155
|
+
feePct: 2,
|
|
156
|
+
symbol: 'SCRAP',
|
|
157
|
+
precision: 0,
|
|
158
|
+
tokenContract: 'scrap.gm',
|
|
159
|
+
})
|
|
160
|
+
expect(counts.wrapcost).toBe(0)
|
|
161
|
+
expect(counts.wrapconfig).toBe(0)
|
|
162
|
+
// getDepositConfig is a BalancesManager concern seeded separately; this stub always calls through.
|
|
163
|
+
expect(counts.depositcfg).toBe(1)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
test('with nothing seeded, falls back to chain for config and cost', async () => {
|
|
167
|
+
const {manager, counts} = stubContext({
|
|
168
|
+
wrapCosts: [{item_type: 3, tier: 2, amount: 500}],
|
|
169
|
+
wrapConfig: {fee_pct: 200, fee_account: 'fee.gm'},
|
|
170
|
+
depositConfig: DEPOSIT,
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
const deposit = await manager.getWrapDeposit(3, 2)
|
|
174
|
+
expect(deposit?.cost).toBe(500n)
|
|
175
|
+
expect(counts.wrapcost).toBe(1)
|
|
176
|
+
expect(counts.wrapconfig).toBe(1)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('reload true bypasses seeds and reaches chain', async () => {
|
|
180
|
+
const {manager, counts} = stubContext({
|
|
181
|
+
wrapCosts: [{item_type: 3, tier: 2, amount: 500}],
|
|
182
|
+
wrapConfig: {fee_pct: 200, fee_account: 'fee.gm'},
|
|
183
|
+
depositConfig: DEPOSIT,
|
|
184
|
+
})
|
|
185
|
+
manager.setWrapCosts([{itemType: 3, tier: 2, units: 500n}])
|
|
186
|
+
manager.setWrapConfig({feePctBasisPoints: 200, feeAccount: 'fee.gm'})
|
|
187
|
+
|
|
188
|
+
await manager.getWrapDeposit(3, 2, {reload: true})
|
|
189
|
+
expect(counts.wrapcost).toBe(1)
|
|
190
|
+
expect(counts.wrapconfig).toBe(1)
|
|
191
|
+
expect(counts.depositcfg).toBe(1)
|
|
192
|
+
})
|
|
193
|
+
})
|
package/src/managers/nft.ts
CHANGED
|
@@ -12,6 +12,17 @@ export interface WrapConfig {
|
|
|
12
12
|
feeAccount: Name
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
export interface WrapConfigInput {
|
|
16
|
+
feePctBasisPoints: number
|
|
17
|
+
feeAccount: NameType
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface WrapCostInput {
|
|
21
|
+
itemType: number
|
|
22
|
+
tier: number
|
|
23
|
+
units: bigint | string | number
|
|
24
|
+
}
|
|
25
|
+
|
|
15
26
|
export interface WrapGate {
|
|
16
27
|
owner: Name
|
|
17
28
|
game: Name
|
|
@@ -39,6 +50,7 @@ export function wrapCostKey(itemType: number, tier: number): UInt64 {
|
|
|
39
50
|
export class NftManager extends BaseManager {
|
|
40
51
|
private cache = new Map<string, NftConfigForItem | null>()
|
|
41
52
|
private wrapConfig?: WrapConfig | null
|
|
53
|
+
private wrapCosts?: Map<string, bigint> | null
|
|
42
54
|
|
|
43
55
|
async getNftConfigForItem(itemId: UInt64Type): Promise<NftConfigForItem | undefined> {
|
|
44
56
|
const id = UInt64.from(itemId)
|
|
@@ -56,6 +68,23 @@ export class NftManager extends BaseManager {
|
|
|
56
68
|
return result ?? undefined
|
|
57
69
|
}
|
|
58
70
|
|
|
71
|
+
setWrapConfig(config: WrapConfigInput | null): void {
|
|
72
|
+
this.wrapConfig = config
|
|
73
|
+
? {
|
|
74
|
+
feePctBasisPoints: config.feePctBasisPoints,
|
|
75
|
+
feeAccount: Name.from(config.feeAccount),
|
|
76
|
+
}
|
|
77
|
+
: null
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
setWrapCosts(costs: WrapCostInput[] | null): void {
|
|
81
|
+
this.wrapCosts = costs
|
|
82
|
+
? new Map(
|
|
83
|
+
costs.map((c) => [wrapCostKey(c.itemType, c.tier).toString(), BigInt(c.units)])
|
|
84
|
+
)
|
|
85
|
+
: null
|
|
86
|
+
}
|
|
87
|
+
|
|
59
88
|
async getWrapConfig(reload = false): Promise<WrapConfig | null> {
|
|
60
89
|
if (!reload && this.wrapConfig !== undefined) {
|
|
61
90
|
return this.wrapConfig
|
|
@@ -69,7 +98,11 @@ export class NftManager extends BaseManager {
|
|
|
69
98
|
return this.wrapConfig
|
|
70
99
|
}
|
|
71
100
|
|
|
72
|
-
async getWrapCost(itemType: number, tier: number): Promise<bigint> {
|
|
101
|
+
async getWrapCost(itemType: number, tier: number, reload = false): Promise<bigint> {
|
|
102
|
+
if (!reload && this.wrapCosts) {
|
|
103
|
+
const seeded = this.wrapCosts.get(wrapCostKey(itemType, tier).toString())
|
|
104
|
+
if (seeded !== undefined) return seeded
|
|
105
|
+
}
|
|
73
106
|
const row = (await this.server.table('wrapcost').get(wrapCostKey(itemType, tier))) as
|
|
74
107
|
| ServerContract.Types.wrapcost_row
|
|
75
108
|
| undefined
|
|
@@ -81,7 +114,7 @@ export class NftManager extends BaseManager {
|
|
|
81
114
|
tier: number,
|
|
82
115
|
opts: {reload?: boolean} = {}
|
|
83
116
|
): Promise<WrapDeposit | null> {
|
|
84
|
-
const cost = await this.getWrapCost(itemType, tier)
|
|
117
|
+
const cost = await this.getWrapCost(itemType, tier, opts.reload)
|
|
85
118
|
if (cost === 0n) return null
|
|
86
119
|
|
|
87
120
|
const wrapConfig = await this.getWrapConfig(opts.reload)
|