@meddleware/nft-gate-client 0.0.2 → 0.0.3
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/CHANGELOG.md +9 -0
- package/package.json +9 -3
- package/src/challenge.ts +3 -0
- package/src/index.ts +29 -2
- package/src/ownership.ts +112 -1
- package/src/proof.ts +2 -0
- package/src/ptb.ts +89 -1
- package/src/types.ts +42 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.0.3] - 2026-08-29
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Gate administration PTB builders (AdminCap-gated): `buildSetPriceTx`, `buildSetPaymentRecipientTx`, `buildSetPausedTx`, `buildSetDefaultUsesTx`, `buildSetSoulboundTx`, `buildSetAutoBurnAtZeroTx`, `buildSetNftNameTx`, `buildSetNftImageUrlTx`, `buildSetNftDescriptionTx`, `buildAirdropTx`, `buildMakeGateImmutableTx`
|
|
13
|
+
- `GateAdminContext` type (`{ packageId, gateId, adminCapId }`) for the management builders
|
|
14
|
+
- Gate discovery helpers: `fetchOwnedGates`, `fetchAdminCaps`, `fetchGate`, `parseAdminCap`, `parseGate`, and the `OwnedGate` type — list and read the gates an operator administers
|
|
15
|
+
- `@throws` annotations on the async ownership / challenge / proof functions
|
|
16
|
+
|
|
8
17
|
## [0.0.1] - 2026-08-27
|
|
9
18
|
|
|
10
19
|
### Added
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meddleware/nft-gate-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Client-side helpers for the access_gate NFT access primitive: ownership queries, purchase/consume PTB builders, challenge signing, and access-proof assembly.",
|
|
6
6
|
"author": "MeddleWare <meddleware@proton.me>",
|
|
@@ -9,7 +9,13 @@
|
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "git+https://github.com/meddleware-org/nft-gate-client.git"
|
|
11
11
|
},
|
|
12
|
-
"keywords": [
|
|
12
|
+
"keywords": [
|
|
13
|
+
"sui",
|
|
14
|
+
"nft",
|
|
15
|
+
"access-control",
|
|
16
|
+
"web3",
|
|
17
|
+
"move"
|
|
18
|
+
],
|
|
13
19
|
"files": [
|
|
14
20
|
"src",
|
|
15
21
|
"CHANGELOG.md"
|
|
@@ -33,4 +39,4 @@
|
|
|
33
39
|
"publishConfig": {
|
|
34
40
|
"access": "public"
|
|
35
41
|
}
|
|
36
|
-
}
|
|
42
|
+
}
|
package/src/challenge.ts
CHANGED
|
@@ -3,6 +3,9 @@ import type { Challenge } from './types.js'
|
|
|
3
3
|
/**
|
|
4
4
|
* Fetch a fresh challenge from a gateway's `GET /v1/challenge` endpoint. Tolerates both
|
|
5
5
|
* `expiresAt` (camelCase) and `expires_at` (snake_case) response shapes.
|
|
6
|
+
*
|
|
7
|
+
* @throws {Error} if the network request fails or the gateway returns a non-2xx status.
|
|
8
|
+
* @throws {Error} if the response body is missing the required `nonce` field.
|
|
6
9
|
*/
|
|
7
10
|
export async function fetchChallenge(
|
|
8
11
|
gatewayHost: string,
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
export type {
|
|
9
9
|
AccessGateConfig,
|
|
10
|
+
GateAdminContext,
|
|
11
|
+
OwnedGate,
|
|
10
12
|
Challenge,
|
|
11
13
|
AccessProof,
|
|
12
14
|
OwnedAccessNft,
|
|
@@ -14,8 +16,33 @@ export type {
|
|
|
14
16
|
SuiObjectClient,
|
|
15
17
|
} from './types.js'
|
|
16
18
|
|
|
17
|
-
export {
|
|
18
|
-
|
|
19
|
+
export {
|
|
20
|
+
fetchAccessNfts,
|
|
21
|
+
ownsAccessNft,
|
|
22
|
+
parseOwnedAccessNft,
|
|
23
|
+
fetchAccessNftById,
|
|
24
|
+
parseAdminCap,
|
|
25
|
+
parseGate,
|
|
26
|
+
fetchAdminCaps,
|
|
27
|
+
fetchGate,
|
|
28
|
+
fetchOwnedGates,
|
|
29
|
+
} from './ownership.js'
|
|
30
|
+
export {
|
|
31
|
+
buildPurchaseTx,
|
|
32
|
+
buildConsumeTx,
|
|
33
|
+
buildCreateGateTx,
|
|
34
|
+
buildSetPriceTx,
|
|
35
|
+
buildSetPaymentRecipientTx,
|
|
36
|
+
buildSetPausedTx,
|
|
37
|
+
buildSetDefaultUsesTx,
|
|
38
|
+
buildSetSoulboundTx,
|
|
39
|
+
buildSetAutoBurnAtZeroTx,
|
|
40
|
+
buildSetNftNameTx,
|
|
41
|
+
buildSetNftImageUrlTx,
|
|
42
|
+
buildSetNftDescriptionTx,
|
|
43
|
+
buildAirdropTx,
|
|
44
|
+
buildMakeGateImmutableTx,
|
|
45
|
+
} from './ptb.js'
|
|
19
46
|
export { fetchChallenge } from './challenge.js'
|
|
20
47
|
export {
|
|
21
48
|
personalMessageForNonce,
|
package/src/ownership.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { OwnedAccessNft, OwnedObjectsClient, SuiObjectClient } from './types.js'
|
|
1
|
+
import type { OwnedAccessNft, OwnedGate, OwnedObjectsClient, SuiObjectClient } from './types.js'
|
|
2
2
|
|
|
3
3
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
4
4
|
|
|
@@ -50,6 +50,8 @@ export function parseOwnedAccessNft(entry: any): OwnedAccessNft | null {
|
|
|
50
50
|
* Typed single-object read of one access NFT by id (`getObject` with `showType`+`showContent`),
|
|
51
51
|
* used when a UI needs the **exact** `usesRemaining` reliably rather than the best-effort parse
|
|
52
52
|
* of an owned-objects page. Returns `null` if the object is missing or not an access NFT.
|
|
53
|
+
*
|
|
54
|
+
* @throws {Error} if the RPC call fails at the network or transport layer.
|
|
53
55
|
*/
|
|
54
56
|
export async function fetchAccessNftById(
|
|
55
57
|
client: SuiObjectClient,
|
|
@@ -65,6 +67,8 @@ export async function fetchAccessNftById(
|
|
|
65
67
|
/**
|
|
66
68
|
* Fetch all access NFTs of `nftType` owned by `owner`, optionally restricted to a specific
|
|
67
69
|
* `gateId`. Uses `getOwnedObjects` filtered by `StructType` (the standard owned-objects query).
|
|
70
|
+
*
|
|
71
|
+
* @throws {Error} if the RPC call fails at the network or transport layer.
|
|
68
72
|
*/
|
|
69
73
|
export async function fetchAccessNfts(
|
|
70
74
|
client: OwnedObjectsClient,
|
|
@@ -87,6 +91,8 @@ export async function fetchAccessNfts(
|
|
|
87
91
|
* True if `owner` holds at least one access NFT of `nftType` (optionally for `gateId`).
|
|
88
92
|
* This is the cheap check a frontend runs to decide whether to show a gated option, and a
|
|
89
93
|
* gateway runs (server-side) as part of access verification.
|
|
94
|
+
*
|
|
95
|
+
* @throws {Error} if the underlying RPC call fails.
|
|
90
96
|
*/
|
|
91
97
|
export async function ownsAccessNft(
|
|
92
98
|
client: OwnedObjectsClient,
|
|
@@ -97,3 +103,108 @@ export async function ownsAccessNft(
|
|
|
97
103
|
const nfts = await fetchAccessNfts(client, owner, nftType, gateId)
|
|
98
104
|
return nfts.length > 0
|
|
99
105
|
}
|
|
106
|
+
|
|
107
|
+
// ── Gate discovery (operator management) ─────────────────────────────────────────
|
|
108
|
+
// An operator holds an `AdminCap` per gate they administer. Discovery: list owned AdminCaps
|
|
109
|
+
// (filtered by StructType), read each cap's `gate_id`, then fetch the shared `Gate` object.
|
|
110
|
+
|
|
111
|
+
/** True if `type` names the `access_gate::AdminCap` struct. */
|
|
112
|
+
function isAdminCapType(type: unknown): boolean {
|
|
113
|
+
return typeof type === 'string' && /::access_gate::AdminCap\b/.test(type)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Parse a single `getOwnedObjects`/`getObject` entry into `{ adminCapId, gateId }`, or `null` if
|
|
118
|
+
* it is not an `AdminCap`. Validates the object **type** when present and reads `fields.gate_id`.
|
|
119
|
+
*/
|
|
120
|
+
export function parseAdminCap(entry: any): { adminCapId: string; gateId: string } | null {
|
|
121
|
+
const obj = entry?.data ?? entry
|
|
122
|
+
const adminCapId: string | undefined = obj?.objectId ?? obj?.content?.fields?.id?.id
|
|
123
|
+
const type: unknown = obj?.type ?? obj?.content?.type
|
|
124
|
+
if (type !== undefined && !isAdminCapType(type)) return null
|
|
125
|
+
const gateId: string | undefined = obj?.content?.fields?.gate_id ?? obj?.content?.fields?.gateId
|
|
126
|
+
if (!adminCapId || !gateId) return null
|
|
127
|
+
return { adminCapId, gateId }
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Parse a `getObject` entry for a `Gate` shared object into an {@link OwnedGate} (minus
|
|
132
|
+
* `adminCapId`, which comes from the owning cap). Returns `null` if the object is missing its
|
|
133
|
+
* expected `Gate` fields.
|
|
134
|
+
*/
|
|
135
|
+
export function parseGate(entry: any): Omit<OwnedGate, 'adminCapId'> | null {
|
|
136
|
+
const obj = entry?.data ?? entry
|
|
137
|
+
const gateId: string | undefined = obj?.objectId ?? obj?.content?.fields?.id?.id
|
|
138
|
+
const f = obj?.content?.fields
|
|
139
|
+
if (!gateId || !f) return null
|
|
140
|
+
return {
|
|
141
|
+
gateId,
|
|
142
|
+
priceMist: BigInt(f.price_mist ?? 0),
|
|
143
|
+
paymentRecipient: String(f.payment_recipient ?? ''),
|
|
144
|
+
defaultUses: BigInt(f.default_uses ?? 0),
|
|
145
|
+
soulbound: Boolean(f.soulbound),
|
|
146
|
+
autoBurnAtZero: Boolean(f.auto_burn_at_zero),
|
|
147
|
+
paused: Boolean(f.paused),
|
|
148
|
+
frozen: Boolean(f.frozen),
|
|
149
|
+
nftName: String(f.nft_name ?? ''),
|
|
150
|
+
nftImageUrl: String(f.nft_image_url ?? ''),
|
|
151
|
+
nftDescription: String(f.nft_description ?? ''),
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* List the `{ adminCapId, gateId }` pairs for every `access_gate::AdminCap` owned by `owner`
|
|
157
|
+
* under `packageId`. Uses `getOwnedObjects` filtered by `StructType` (the standard query).
|
|
158
|
+
*
|
|
159
|
+
* @throws {Error} if the underlying RPC call fails.
|
|
160
|
+
*/
|
|
161
|
+
export async function fetchAdminCaps(
|
|
162
|
+
client: OwnedObjectsClient,
|
|
163
|
+
owner: string,
|
|
164
|
+
packageId: string,
|
|
165
|
+
): Promise<{ adminCapId: string; gateId: string }[]> {
|
|
166
|
+
const { data } = await client.getOwnedObjects({
|
|
167
|
+
owner,
|
|
168
|
+
filter: { StructType: `${packageId}::access_gate::AdminCap` },
|
|
169
|
+
options: { showContent: true, showType: true },
|
|
170
|
+
})
|
|
171
|
+
return (data ?? [])
|
|
172
|
+
.map(parseAdminCap)
|
|
173
|
+
.filter((c): c is { adminCapId: string; gateId: string } => c !== null)
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Typed single-object read of one `Gate` by id, returning its parsed state (without `adminCapId`).
|
|
178
|
+
* Returns `null` if the object is missing or not a `Gate`.
|
|
179
|
+
*
|
|
180
|
+
* @throws {Error} if the RPC call fails at the network or transport layer.
|
|
181
|
+
*/
|
|
182
|
+
export async function fetchGate(
|
|
183
|
+
client: SuiObjectClient,
|
|
184
|
+
gateId: string,
|
|
185
|
+
): Promise<Omit<OwnedGate, 'adminCapId'> | null> {
|
|
186
|
+
const res = await client.getObject({ id: gateId, options: { showType: true, showContent: true } })
|
|
187
|
+
return parseGate(res)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Fetch every gate `owner` administers: list their owned `AdminCap`s, then fetch each referenced
|
|
192
|
+
* `Gate` shared object and merge in the owning `adminCapId`. Gates whose object can no longer be
|
|
193
|
+
* read (e.g. deleted) are skipped.
|
|
194
|
+
*
|
|
195
|
+
* @throws {Error} if an underlying RPC call fails at the network or transport layer.
|
|
196
|
+
*/
|
|
197
|
+
export async function fetchOwnedGates(
|
|
198
|
+
client: OwnedObjectsClient & SuiObjectClient,
|
|
199
|
+
owner: string,
|
|
200
|
+
packageId: string,
|
|
201
|
+
): Promise<OwnedGate[]> {
|
|
202
|
+
const caps = await fetchAdminCaps(client, owner, packageId)
|
|
203
|
+
const gates = await Promise.all(
|
|
204
|
+
caps.map(async ({ adminCapId, gateId }) => {
|
|
205
|
+
const gate = await fetchGate(client, gateId)
|
|
206
|
+
return gate ? { ...gate, adminCapId } : null
|
|
207
|
+
}),
|
|
208
|
+
)
|
|
209
|
+
return gates.filter((g): g is OwnedGate => g !== null)
|
|
210
|
+
}
|
package/src/proof.ts
CHANGED
|
@@ -38,6 +38,8 @@ export type PersonalMessageSigner = (message: Uint8Array) => Promise<{ signature
|
|
|
38
38
|
/**
|
|
39
39
|
* Sign a challenge and assemble the encoded access-proof token to hand to any gateway as its
|
|
40
40
|
* auth bearer (e.g. an upload-relay client's auth-token option, an `Authorization` header).
|
|
41
|
+
*
|
|
42
|
+
* @throws {Error} if the wallet signer rejects or fails to sign the message.
|
|
41
43
|
*/
|
|
42
44
|
export async function buildAccessProof(opts: {
|
|
43
45
|
address: string
|
package/src/ptb.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Transaction } from '@mysten/sui/transactions'
|
|
2
|
-
import type { AccessGateConfig } from './types.js'
|
|
2
|
+
import type { AccessGateConfig, GateAdminContext } from './types.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Build a PTB that purchases access: split `priceMist` from the gas coin and call
|
|
@@ -69,3 +69,91 @@ export function buildCreateGateTx(
|
|
|
69
69
|
})
|
|
70
70
|
return tx
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
// ── Gate administration (AdminCap-gated) ─────────────────────────────────────────
|
|
74
|
+
// Builders for the operator management surface. Each calls an `assert_admin`-gated entry
|
|
75
|
+
// point with `[adminCap, gate, <value>]`; the operator signs + executes with their wallet.
|
|
76
|
+
// The on-chain call aborts (`E_WRONG_GATE` / `E_FROZEN`) if the cap/gate mismatch or the
|
|
77
|
+
// gate is frozen, so these never need to pre-check.
|
|
78
|
+
|
|
79
|
+
/** The element type accepted by a `moveCall`'s `arguments` array. */
|
|
80
|
+
type MoveCallArg = NonNullable<Parameters<Transaction['moveCall']>[0]['arguments']>[number]
|
|
81
|
+
|
|
82
|
+
/** Build a single-`moveCall` admin PTB: `<fn>(adminCap, gate, ...extraArgs)`. */
|
|
83
|
+
function buildGateAdminCall(
|
|
84
|
+
ctx: GateAdminContext,
|
|
85
|
+
fn: string,
|
|
86
|
+
extraArgs: (tx: Transaction) => MoveCallArg[],
|
|
87
|
+
): Transaction {
|
|
88
|
+
const tx = new Transaction()
|
|
89
|
+
tx.moveCall({
|
|
90
|
+
target: `${ctx.packageId}::access_gate::${fn}`,
|
|
91
|
+
arguments: [tx.object(ctx.adminCapId), tx.object(ctx.gateId), ...extraArgs(tx)],
|
|
92
|
+
})
|
|
93
|
+
return tx
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Set the gate price (in MIST) charged by future `purchase` calls (0 = free). */
|
|
97
|
+
export function buildSetPriceTx(ctx: GateAdminContext, priceMist: bigint | number): Transaction {
|
|
98
|
+
return buildGateAdminCall(ctx, 'set_price', (tx) => [tx.pure.u64(priceMist)])
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Redirect future purchase payments to a new recipient address. */
|
|
102
|
+
export function buildSetPaymentRecipientTx(ctx: GateAdminContext, recipient: string): Transaction {
|
|
103
|
+
return buildGateAdminCall(ctx, 'set_payment_recipient', (tx) => [tx.pure.address(recipient)])
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Pause or unpause `purchase` (paused ⇒ `purchase` aborts with `E_PAUSED`). */
|
|
107
|
+
export function buildSetPausedTx(ctx: GateAdminContext, paused: boolean): Transaction {
|
|
108
|
+
return buildGateAdminCall(ctx, 'set_paused', (tx) => [tx.pure.bool(paused)])
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Change the default uses for future mints (0 ⇒ unlimited pass; N ⇒ single-use with N). */
|
|
112
|
+
export function buildSetDefaultUsesTx(ctx: GateAdminContext, defaultUses: bigint | number): Transaction {
|
|
113
|
+
return buildGateAdminCall(ctx, 'set_default_uses', (tx) => [tx.pure.u64(defaultUses)])
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Switch the soulbound flag for future mints (does not affect already-minted NFTs). */
|
|
117
|
+
export function buildSetSoulboundTx(ctx: GateAdminContext, soulbound: boolean): Transaction {
|
|
118
|
+
return buildGateAdminCall(ctx, 'set_soulbound', (tx) => [tx.pure.bool(soulbound)])
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Toggle the auto-burn-at-zero policy for future mints. */
|
|
122
|
+
export function buildSetAutoBurnAtZeroTx(ctx: GateAdminContext, autoBurn: boolean): Transaction {
|
|
123
|
+
return buildGateAdminCall(ctx, 'set_auto_burn_at_zero', (tx) => [tx.pure.bool(autoBurn)])
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Update the default NFT display name for future mints. */
|
|
127
|
+
export function buildSetNftNameTx(ctx: GateAdminContext, name: string): Transaction {
|
|
128
|
+
return buildGateAdminCall(ctx, 'set_nft_name', (tx) => [tx.pure.string(name)])
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/** Update the default NFT image URL for future mints. */
|
|
132
|
+
export function buildSetNftImageUrlTx(ctx: GateAdminContext, url: string): Transaction {
|
|
133
|
+
return buildGateAdminCall(ctx, 'set_nft_image_url', (tx) => [tx.pure.string(url)])
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** Update the default NFT description for future mints. */
|
|
137
|
+
export function buildSetNftDescriptionTx(ctx: GateAdminContext, description: string): Transaction {
|
|
138
|
+
return buildGateAdminCall(ctx, 'set_nft_description', (tx) => [tx.pure.string(description)])
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/** AdminCap-gated free grant (airdrop) of the gate's NFT flavour to `recipient`. */
|
|
142
|
+
export function buildAirdropTx(ctx: GateAdminContext, recipient: string): Transaction {
|
|
143
|
+
return buildGateAdminCall(ctx, 'airdrop', (tx) => [tx.pure.address(recipient)])
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Make the gate immutable — **irreversible**. Consumes the `AdminCap` (passed by value) and sets
|
|
148
|
+
* `Gate.frozen = true`, permanently ending all setters and `airdrop`. `purchase`/`consume` remain
|
|
149
|
+
* permissionless. Grant everything first, then freeze.
|
|
150
|
+
*/
|
|
151
|
+
export function buildMakeGateImmutableTx(ctx: GateAdminContext): Transaction {
|
|
152
|
+
const tx = new Transaction()
|
|
153
|
+
tx.moveCall({
|
|
154
|
+
target: `${ctx.packageId}::access_gate::make_gate_immutable`,
|
|
155
|
+
// cap is consumed by value; gate is &mut.
|
|
156
|
+
arguments: [tx.object(ctx.adminCapId), tx.object(ctx.gateId)],
|
|
157
|
+
})
|
|
158
|
+
return tx
|
|
159
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -23,6 +23,48 @@ export interface AccessGateConfig {
|
|
|
23
23
|
soulbound?: boolean
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Identifies a gate an operator administers, for the AdminCap-gated management PTB builders
|
|
28
|
+
* (setters, airdrop, freeze). The three ids together authorise a call: `adminCapId` must be the
|
|
29
|
+
* `AdminCap` whose `gate_id` matches `gateId`, under the published `packageId`.
|
|
30
|
+
*/
|
|
31
|
+
export interface GateAdminContext {
|
|
32
|
+
/** Published `access_gate` package ID. */
|
|
33
|
+
packageId: string
|
|
34
|
+
/** The shared `Gate` object ID being administered. */
|
|
35
|
+
gateId: string
|
|
36
|
+
/** The `AdminCap` object ID authorised over `gateId` (held by the operator). */
|
|
37
|
+
adminCapId: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** A gate an operator administers, parsed from its on-chain `Gate` object + owning `AdminCap`. */
|
|
41
|
+
export interface OwnedGate {
|
|
42
|
+
/** The shared `Gate` object ID. */
|
|
43
|
+
gateId: string
|
|
44
|
+
/** The `AdminCap` object ID that authorises administering this gate. */
|
|
45
|
+
adminCapId: string
|
|
46
|
+
/** Price in MIST charged by `purchase` (0 = free). */
|
|
47
|
+
priceMist: bigint
|
|
48
|
+
/** Address that receives the operator share of each paid `purchase`. */
|
|
49
|
+
paymentRecipient: string
|
|
50
|
+
/** 0 ⇒ unlimited passes; N ⇒ single-use NFTs with N uses. */
|
|
51
|
+
defaultUses: bigint
|
|
52
|
+
/** Whether newly-minted NFTs are soulbound. */
|
|
53
|
+
soulbound: boolean
|
|
54
|
+
/** Whether a single-use NFT is deleted (vs. kept as a receipt) at zero uses. */
|
|
55
|
+
autoBurnAtZero: boolean
|
|
56
|
+
/** Whether `purchase` is currently disabled. */
|
|
57
|
+
paused: boolean
|
|
58
|
+
/** Whether the gate has been made immutable (all admin/airdrop permanently disabled). */
|
|
59
|
+
frozen: boolean
|
|
60
|
+
/** Default NFT display name minted into future NFTs. */
|
|
61
|
+
nftName: string
|
|
62
|
+
/** Default NFT image URL minted into future NFTs. */
|
|
63
|
+
nftImageUrl: string
|
|
64
|
+
/** Default NFT description minted into future NFTs. */
|
|
65
|
+
nftDescription: string
|
|
66
|
+
}
|
|
67
|
+
|
|
26
68
|
/** A server-issued, time-bound challenge the wallet signs to prove control of an address. */
|
|
27
69
|
export interface Challenge {
|
|
28
70
|
/** Opaque nonce (as issued by the gateway; treated as a UTF-8 string end-to-end). */
|