sui-effect 0.1.0
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/AGENTS.md +209 -0
- package/LICENSE +21 -0
- package/LLMS.md +6707 -0
- package/README.md +300 -0
- package/dist/domain/bcs.d.ts +101 -0
- package/dist/domain/bcs.d.ts.map +1 -0
- package/dist/domain/bcs.js +183 -0
- package/dist/domain/bcs.js.map +1 -0
- package/dist/domain/errors.d.ts +595 -0
- package/dist/domain/errors.d.ts.map +1 -0
- package/dist/domain/errors.js +476 -0
- package/dist/domain/errors.js.map +1 -0
- package/dist/domain/executed.d.ts +325 -0
- package/dist/domain/executed.d.ts.map +1 -0
- package/dist/domain/executed.js +253 -0
- package/dist/domain/executed.js.map +1 -0
- package/dist/domain/journal-entry.d.ts +468 -0
- package/dist/domain/journal-entry.d.ts.map +1 -0
- package/dist/domain/journal-entry.js +63 -0
- package/dist/domain/journal-entry.js.map +1 -0
- package/dist/domain/schemas.d.ts +950 -0
- package/dist/domain/schemas.d.ts.map +1 -0
- package/dist/domain/schemas.js +571 -0
- package/dist/domain/schemas.js.map +1 -0
- package/dist/domain/sui-schema.d.ts +12 -0
- package/dist/domain/sui-schema.d.ts.map +1 -0
- package/dist/domain/sui-schema.js +12 -0
- package/dist/domain/sui-schema.js.map +1 -0
- package/dist/extension.d.ts +7 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +7 -0
- package/dist/extension.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +18 -0
- package/dist/internal.d.ts.map +1 -0
- package/dist/internal.js +18 -0
- package/dist/internal.js.map +1 -0
- package/dist/journal.d.ts +51 -0
- package/dist/journal.d.ts.map +1 -0
- package/dist/journal.js +18 -0
- package/dist/journal.js.map +1 -0
- package/dist/script.d.ts +7 -0
- package/dist/script.d.ts.map +1 -0
- package/dist/script.js +7 -0
- package/dist/script.js.map +1 -0
- package/dist/services/Journal.d.ts +76 -0
- package/dist/services/Journal.d.ts.map +1 -0
- package/dist/services/Journal.js +70 -0
- package/dist/services/Journal.js.map +1 -0
- package/dist/services/JournalKeyValueStore.d.ts +73 -0
- package/dist/services/JournalKeyValueStore.d.ts.map +1 -0
- package/dist/services/JournalKeyValueStore.js +155 -0
- package/dist/services/JournalKeyValueStore.js.map +1 -0
- package/dist/services/Script.d.ts +210 -0
- package/dist/services/Script.d.ts.map +1 -0
- package/dist/services/Script.js +441 -0
- package/dist/services/Script.js.map +1 -0
- package/dist/services/Signer.d.ts +132 -0
- package/dist/services/Signer.d.ts.map +1 -0
- package/dist/services/Signer.js +158 -0
- package/dist/services/Signer.js.map +1 -0
- package/dist/services/SubmitConfig.d.ts +175 -0
- package/dist/services/SubmitConfig.d.ts.map +1 -0
- package/dist/services/SubmitConfig.js +52 -0
- package/dist/services/SubmitConfig.js.map +1 -0
- package/dist/services/Sui.d.ts +295 -0
- package/dist/services/Sui.d.ts.map +1 -0
- package/dist/services/Sui.js +414 -0
- package/dist/services/Sui.js.map +1 -0
- package/dist/services/SuiCore.d.ts +227 -0
- package/dist/services/SuiCore.d.ts.map +1 -0
- package/dist/services/SuiCore.js +400 -0
- package/dist/services/SuiCore.js.map +1 -0
- package/dist/services/SuiCoreFake.d.ts +278 -0
- package/dist/services/SuiCoreFake.d.ts.map +1 -0
- package/dist/services/SuiCoreFake.js +1003 -0
- package/dist/services/SuiCoreFake.js.map +1 -0
- package/dist/services/SuiExtension.d.ts +208 -0
- package/dist/services/SuiExtension.d.ts.map +1 -0
- package/dist/services/SuiExtension.js +355 -0
- package/dist/services/SuiExtension.js.map +1 -0
- package/dist/services/SuiGraphQL.d.ts +98 -0
- package/dist/services/SuiGraphQL.d.ts.map +1 -0
- package/dist/services/SuiGraphQL.js +118 -0
- package/dist/services/SuiGraphQL.js.map +1 -0
- package/dist/services/Tx.d.ts +687 -0
- package/dist/services/Tx.d.ts.map +1 -0
- package/dist/services/Tx.js +1224 -0
- package/dist/services/Tx.js.map +1 -0
- package/dist/testing.d.ts +88 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +163 -0
- package/dist/testing.js.map +1 -0
- package/dist/tx.d.ts +24 -0
- package/dist/tx.d.ts.map +1 -0
- package/dist/tx.js +24 -0
- package/dist/tx.js.map +1 -0
- package/docs/extensions.md +1685 -0
- package/examples/extension-template/README.md +170 -0
- package/examples/extension-template/package.json +44 -0
- package/examples/extension-template/scripts/check-package.ts +145 -0
- package/examples/extension-template/src/Escrow.ts +445 -0
- package/examples/extension-template/src/Platform.ts +136 -0
- package/examples/extension-template/src/errors.ts +61 -0
- package/examples/extension-template/src/extension.ts +63 -0
- package/examples/extension-template/src/index.ts +34 -0
- package/examples/extension-template/src/schema.ts +158 -0
- package/examples/extension-template/src/upstream.ts +66 -0
- package/examples/extension-template/test/escrow.test.ts +559 -0
- package/examples/extension-template/tsconfig.build.json +26 -0
- package/examples/extension-template/tsconfig.json +35 -0
- package/package.json +87 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Promise face, derived rather than maintained.
|
|
3
|
+
*
|
|
4
|
+
* `SuiExtension.fromService` walks the service interface once: `Effect` members
|
|
5
|
+
* become Promise methods, `Stream` members become `AsyncIterable`s, nested
|
|
6
|
+
* namespaces are mapped recursively, plain values pass through, and a rejection
|
|
7
|
+
* is the same tagged error instance an Effect caller would have caught, so a
|
|
8
|
+
* Promise consumer can still switch on `_tag`.
|
|
9
|
+
*
|
|
10
|
+
* There is no second implementation to keep in step, which is the whole point.
|
|
11
|
+
*/
|
|
12
|
+
import { SuiExtension } from "sui-effect/extension"
|
|
13
|
+
import type { EscrowOptions } from "./Escrow.ts"
|
|
14
|
+
import { Escrow } from "./Escrow.ts"
|
|
15
|
+
|
|
16
|
+
/** What a `$extend` registration needs beyond what the layer does. */
|
|
17
|
+
export interface EscrowRegistrationOptions extends EscrowOptions {
|
|
18
|
+
/**
|
|
19
|
+
* The chain identifier the node must be on, as `getChainIdentifier` reports
|
|
20
|
+
* it.
|
|
21
|
+
*
|
|
22
|
+
* **Required on `devnet`, `localnet` and any custom network**, because a
|
|
23
|
+
* `warm` registration takes the chain id rather than asking for it and there
|
|
24
|
+
* is no built-in entry for those; `register` throws without it. On `mainnet`
|
|
25
|
+
* and `testnet` the built-in table answers and this is optional.
|
|
26
|
+
*
|
|
27
|
+
* Give the same id to **every** registration on one client. The base `Sui`,
|
|
28
|
+
* its transport and its sender-lock map are shared per client **per chain
|
|
29
|
+
* id**, so two registrations that disagree get two of everything and two
|
|
30
|
+
* `Tx.run`s for one address stop serializing.
|
|
31
|
+
*/
|
|
32
|
+
readonly chainId?: string
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The registration a Promise consumer passes to `client.$extend(...)`.
|
|
37
|
+
*
|
|
38
|
+
* ```ts
|
|
39
|
+
* const client = new SuiGrpcClient({ network: "testnet", baseUrl }).$extend(escrow(options))
|
|
40
|
+
* const info = await client.escrow.get(id)
|
|
41
|
+
* for await (const item of client.escrow.owned.stream(owner)) console.log(item.id)
|
|
42
|
+
* await client.escrow.dispose()
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* It is registered `warm`, like `platform` in `Platform.ts`: the service has
|
|
46
|
+
* synchronous members — `packageId`, the `claim` recipe fragment, the codecs —
|
|
47
|
+
* and a consumer that reads one the moment it registers should get the value
|
|
48
|
+
* rather than a placeholder that throws `ExtensionNotReady`. Neither layer
|
|
49
|
+
* touches the network at build, which is what `warm` requires.
|
|
50
|
+
*
|
|
51
|
+
* The runtime is built inside `register`, over `SuiCore.layerFromClient(client)`,
|
|
52
|
+
* a `Sui` pinned to `options.chainId` and `Escrow.layer`, so the extension and
|
|
53
|
+
* the consumer share one transport, one chain identity and one sender-lock map.
|
|
54
|
+
*
|
|
55
|
+
* Throws out of `register` when the network has no built-in chain identifier
|
|
56
|
+
* and `options.chainId` was not given.
|
|
57
|
+
*/
|
|
58
|
+
export const escrow = (options: EscrowRegistrationOptions) =>
|
|
59
|
+
SuiExtension.fromService(Escrow, {
|
|
60
|
+
name: "escrow",
|
|
61
|
+
layer: Escrow.layer(options),
|
|
62
|
+
warm: options.chainId === undefined ? {} : { chainId: options.chainId }
|
|
63
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@your-org/example-extension`: the public surface.
|
|
3
|
+
*
|
|
4
|
+
* One service, its layers, its errors, its schemas, and the derived Promise
|
|
5
|
+
* registration. Nothing from `upstream.ts` is re-exported: upstream types are
|
|
6
|
+
* narrowed to sui-effect schemas inside the service and never reach a consumer.
|
|
7
|
+
*/
|
|
8
|
+
export {
|
|
9
|
+
DEPLOYMENTS,
|
|
10
|
+
Escrow,
|
|
11
|
+
type ClaimForError,
|
|
12
|
+
type EscrowDeployment,
|
|
13
|
+
type EscrowFields,
|
|
14
|
+
type EscrowObject,
|
|
15
|
+
type EscrowOptions,
|
|
16
|
+
type EscrowService
|
|
17
|
+
} from "./Escrow.ts"
|
|
18
|
+
export { EscrowNotFound, EscrowSettlementUnknown, EscrowUnsupportedNetwork } from "./errors.ts"
|
|
19
|
+
export { escrow, type EscrowRegistrationOptions } from "./extension.ts"
|
|
20
|
+
export {
|
|
21
|
+
Platform,
|
|
22
|
+
platform,
|
|
23
|
+
type PlatformOptions,
|
|
24
|
+
type PlatformRegistrationOptions,
|
|
25
|
+
type PlatformService
|
|
26
|
+
} from "./Platform.ts"
|
|
27
|
+
export {
|
|
28
|
+
ESCROW_PACKAGE,
|
|
29
|
+
EscrowContent,
|
|
30
|
+
escrowType,
|
|
31
|
+
receiptType,
|
|
32
|
+
Settlement,
|
|
33
|
+
SettlementContent
|
|
34
|
+
} from "./schema.ts"
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Move layouts this package reads, bridged into `Schema`.
|
|
3
|
+
*
|
|
4
|
+
* `SuiSchema.bcs(layout, type)` is a `Schema.Codec<T, Uint8Array>` that also
|
|
5
|
+
* records the Move type, so `sui.getObject(id, { schema })` checks the object's
|
|
6
|
+
* type tag before it parses a single byte and a mismatch is a `DecodeError`
|
|
7
|
+
* naming both types rather than a confusing parse failure.
|
|
8
|
+
*/
|
|
9
|
+
import { bcs } from "@mysten/sui/bcs"
|
|
10
|
+
import { DateTime, Effect, Schema, SchemaIssue, SchemaTransformation } from "effect"
|
|
11
|
+
import { ObjectId, SuiAddress, SuiSchema } from "sui-effect"
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The package the template's example type lives in, and the default this
|
|
15
|
+
* release ships. Replace it with yours.
|
|
16
|
+
*/
|
|
17
|
+
export const ESCROW_PACKAGE = "0x0000000000000000000000000000000000000000000000000000000000000002"
|
|
18
|
+
|
|
19
|
+
/** The BCS layout of `escrow::Escrow`, which is the same whatever it was published to. */
|
|
20
|
+
const EscrowBcs = bcs.struct("Escrow", {
|
|
21
|
+
id: bcs.Address,
|
|
22
|
+
owner: bcs.Address,
|
|
23
|
+
amount: bcs.u64()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
/** The Move type of an escrow, under a given type origin. */
|
|
27
|
+
export const escrowType = (typeOrigin: string): string =>
|
|
28
|
+
`${typeOrigin}::escrow::Escrow`
|
|
29
|
+
|
|
30
|
+
/** The Move type of a claim receipt, which `claimFor` expects to be created. */
|
|
31
|
+
export const receiptType = (typeOrigin: string): string =>
|
|
32
|
+
`${typeOrigin}::escrow::Receipt`
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `escrow::Escrow`, the object this extension reads, **as a function of the
|
|
36
|
+
* package it lives in**.
|
|
37
|
+
*
|
|
38
|
+
* A Move type name contains its package id, so a codec built from a hard-coded
|
|
39
|
+
* constant checks the wrong type the moment a consumer configures a different
|
|
40
|
+
* package: `getObject(id, { schema })` compares the object's tag before it
|
|
41
|
+
* parses a byte, and a correctly encoded object under the configured package
|
|
42
|
+
* fails with `DecodeError`. Every type-shaped constant in an extension takes
|
|
43
|
+
* the package id the service was built with, and the service passes its own.
|
|
44
|
+
*
|
|
45
|
+
* **Which package id.** The one that appears in a type name is the **type
|
|
46
|
+
* origin**: the package the type was *first* published in. Upgrading a package
|
|
47
|
+
* gives it a new id for *calls*, and the type origin does not move. So an
|
|
48
|
+
* extension over an upgraded package carries two ids — `packageId` for
|
|
49
|
+
* `moveCall` targets, `typeOrigin` for codecs, filters and receipt types — and
|
|
50
|
+
* they are the same value until the first upgrade. `Escrow.layer` takes both.
|
|
51
|
+
*/
|
|
52
|
+
export const EscrowContent = (typeOrigin: string) => SuiSchema.bcs(
|
|
53
|
+
EscrowBcs,
|
|
54
|
+
escrowType(typeOrigin)
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The Move layout of `escrow::Settlement`, whose fields are `snake_case`
|
|
59
|
+
* because Move's are.
|
|
60
|
+
*/
|
|
61
|
+
const SettlementBcs = bcs.struct("Settlement", {
|
|
62
|
+
escrow_id: bcs.Address,
|
|
63
|
+
settled_at_ms: bcs.u64(),
|
|
64
|
+
claimed_by: bcs.Address
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The domain type a consumer of this package sees: `camelCase`, branded ids,
|
|
69
|
+
* a `DateTime` instead of a string of milliseconds.
|
|
70
|
+
*
|
|
71
|
+
* The mapping lives in `Schema.decodeTo`, never in a custom `parse`: the bridge
|
|
72
|
+
* needs a real `BcsType` so it can re-serialize what it parsed and reject
|
|
73
|
+
* trailing bytes, and a domain type is not a BCS layout.
|
|
74
|
+
*/
|
|
75
|
+
export class Settlement extends Schema.Class<Settlement>("Settlement")({
|
|
76
|
+
escrowId: ObjectId,
|
|
77
|
+
settledAt: Schema.DateTimeUtc,
|
|
78
|
+
claimedBy: SuiAddress
|
|
79
|
+
}) {}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The halfway shape the transformation produces: the domain field names, before
|
|
83
|
+
* `Settlement`'s own schema brands the ids.
|
|
84
|
+
*/
|
|
85
|
+
interface SettlementParts {
|
|
86
|
+
readonly escrowId: string
|
|
87
|
+
readonly settledAt: DateTime.Utc
|
|
88
|
+
readonly claimedBy: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The composed codec: BCS bytes to `Settlement`, and back.
|
|
93
|
+
*
|
|
94
|
+
* `SuiSchema.bcs(...)` decodes the bytes into the Move shape;
|
|
95
|
+
* `Schema.decodeTo(Settlement, SchemaTransformation.transform({ decode, encode }))`
|
|
96
|
+
* renames the fields, and `Settlement` itself does the rest — branding the ids
|
|
97
|
+
* and checking them. The Move type the bridge recorded survives the
|
|
98
|
+
* composition, so
|
|
99
|
+
* `sui.getObject(id, { schema: SettlementContent })` still checks the object's
|
|
100
|
+
* type tag before parsing a byte.
|
|
101
|
+
*
|
|
102
|
+
* Two details worth copying:
|
|
103
|
+
*
|
|
104
|
+
* - **`decode` produces the target's field shape, not an instance.** `decodeTo`
|
|
105
|
+
* sits between the source type and the target schema, which is what lets the
|
|
106
|
+
* target's own checks — the `ObjectId` and `SuiAddress` brands here — run
|
|
107
|
+
* afterwards.
|
|
108
|
+
* - **`encode` is the inverse mapper and is not optional.** A codec that cannot
|
|
109
|
+
* encode is one `Schema.encodeUnknownEffect` fails on, and the compiler asks
|
|
110
|
+
* for it here rather than at the call site.
|
|
111
|
+
* - **A mapping that can fail uses `transformOrFail`.** `transform` is for total
|
|
112
|
+
* mappings; a body that throws produces a defect, and a byte that was wrong on
|
|
113
|
+
* the wire deserves a failure.
|
|
114
|
+
*
|
|
115
|
+
* A failure *inside* this transform — an id that is not an address, a timestamp
|
|
116
|
+
* that is not a time — is still a `DecodeError` from `SuiSchema.decode` and
|
|
117
|
+
* `sui.getObject`, with the same fields: the domain mapping is part of the
|
|
118
|
+
* boundary, not a step after it.
|
|
119
|
+
*/
|
|
120
|
+
export const SettlementContent = (typeOrigin: string) =>
|
|
121
|
+
SuiSchema.bcs(
|
|
122
|
+
SettlementBcs,
|
|
123
|
+
`${typeOrigin}::escrow::Settlement`
|
|
124
|
+
).pipe(
|
|
125
|
+
Schema.decodeTo(
|
|
126
|
+
Settlement,
|
|
127
|
+
SchemaTransformation.transformOrFail<SettlementParts, typeof SettlementBcs.$inferType>({
|
|
128
|
+
decode: (fields, options) =>
|
|
129
|
+
// `transformOrFail`, not `transform`, because one of these mappings can
|
|
130
|
+
// fail: a `u64` of milliseconds is not necessarily a time. A `transform`
|
|
131
|
+
// whose body throws is a **defect**, which is not what a bad byte on the
|
|
132
|
+
// wire should be; failing with a `SchemaIssue` here is what makes it a
|
|
133
|
+
// `DecodeError` like any other.
|
|
134
|
+
Effect.map(
|
|
135
|
+
Effect.fromOption(
|
|
136
|
+
DateTime.make(Number(fields.settled_at_ms)),
|
|
137
|
+
() =>
|
|
138
|
+
new SchemaIssue.InvalidValue(
|
|
139
|
+
{ message: `settled_at_ms ${fields.settled_at_ms} is not a time` },
|
|
140
|
+
fields,
|
|
141
|
+
options
|
|
142
|
+
)
|
|
143
|
+
),
|
|
144
|
+
(settledAt): SettlementParts => ({
|
|
145
|
+
escrowId: fields.escrow_id,
|
|
146
|
+
settledAt,
|
|
147
|
+
claimedBy: fields.claimed_by
|
|
148
|
+
})
|
|
149
|
+
),
|
|
150
|
+
encode: (settlement) =>
|
|
151
|
+
Effect.succeed({
|
|
152
|
+
escrow_id: settlement.escrowId,
|
|
153
|
+
settled_at_ms: String(DateTime.toEpochMillis(settlement.settledAt)),
|
|
154
|
+
claimed_by: settlement.claimedBy
|
|
155
|
+
})
|
|
156
|
+
})
|
|
157
|
+
)
|
|
158
|
+
)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A stand-in for the third-party Promise package an extension wraps.
|
|
3
|
+
*
|
|
4
|
+
* In a real extension this file does not exist: it is an `import` of the
|
|
5
|
+
* upstream SDK (`@some-org/escrow-sdk`), and everything below is its surface.
|
|
6
|
+
* It is here so the guide's "wrapping an upstream Promise package" section has
|
|
7
|
+
* real code to point at: one helper that needs the SDK client object, and one
|
|
8
|
+
* that does not.
|
|
9
|
+
*
|
|
10
|
+
* Note what it is not: it is not exported from `src/index.ts`. Upstream types
|
|
11
|
+
* never reach a consumer of this package; they are narrowed to sui-effect
|
|
12
|
+
* schemas first.
|
|
13
|
+
*/
|
|
14
|
+
import type { ClientWithCoreApi } from "@mysten/sui/client"
|
|
15
|
+
|
|
16
|
+
/** What the operator's settlement service answers with. Untyped on purpose: upstream JSON. */
|
|
17
|
+
export interface SettlementResponse {
|
|
18
|
+
readonly status: string
|
|
19
|
+
readonly [key: string]: unknown
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** The upstream client surface. */
|
|
23
|
+
export interface SettlementApi {
|
|
24
|
+
/**
|
|
25
|
+
* Tells the operator that a claim landed. Needs no Sui client: a pure
|
|
26
|
+
* Promise helper, which is the `Effect.tryPromise` case.
|
|
27
|
+
*/
|
|
28
|
+
readonly notifyClaim: (
|
|
29
|
+
input: { readonly escrowId: string; readonly digest: string },
|
|
30
|
+
signal?: AbortSignal
|
|
31
|
+
) => Promise<SettlementResponse>
|
|
32
|
+
/**
|
|
33
|
+
* Reads the fee collector the package was published with. Needs the SDK
|
|
34
|
+
* client object, which is the `SuiCore.use` case.
|
|
35
|
+
*/
|
|
36
|
+
readonly resolveFeeCollector: (
|
|
37
|
+
client: ClientWithCoreApi,
|
|
38
|
+
packageId: string,
|
|
39
|
+
signal?: AbortSignal
|
|
40
|
+
) => Promise<unknown>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** The upstream constructor: a base URL and an API key. */
|
|
44
|
+
export const settlementApi = (options: {
|
|
45
|
+
readonly url: string
|
|
46
|
+
readonly apiKey: string
|
|
47
|
+
}): SettlementApi => ({
|
|
48
|
+
notifyClaim: async (input, signal) => {
|
|
49
|
+
const response = await fetch(`${options.url}/claims`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${options.apiKey}` },
|
|
52
|
+
body: JSON.stringify(input),
|
|
53
|
+
...(signal === undefined ? {} : { signal })
|
|
54
|
+
})
|
|
55
|
+
if (!response.ok) throw new Error(`settlement service answered ${response.status}`)
|
|
56
|
+
return await response.json() as SettlementResponse
|
|
57
|
+
},
|
|
58
|
+
resolveFeeCollector: async (client, packageId, signal) => {
|
|
59
|
+
const { object } = await client.core.getObject({
|
|
60
|
+
objectId: packageId,
|
|
61
|
+
...(signal === undefined ? {} : { signal })
|
|
62
|
+
})
|
|
63
|
+
const owner = object.owner
|
|
64
|
+
return owner.$kind === "AddressOwner" ? owner.AddressOwner : null
|
|
65
|
+
}
|
|
66
|
+
})
|