@silvana-one/nft 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/README.md +1400 -0
- package/dist/node/admin/advanced.d.ts +469 -0
- package/dist/node/admin/advanced.js +525 -0
- package/dist/node/admin/advanced.js.map +1 -0
- package/dist/node/admin/index.d.ts +1 -0
- package/dist/node/admin/index.js +2 -0
- package/dist/node/admin/index.js.map +1 -0
- package/dist/node/contracts/admin.d.ts +140 -0
- package/dist/node/contracts/admin.js +336 -0
- package/dist/node/contracts/admin.js.map +1 -0
- package/dist/node/contracts/collection.d.ts +551 -0
- package/dist/node/contracts/collection.js +1049 -0
- package/dist/node/contracts/collection.js.map +1 -0
- package/dist/node/contracts/index.d.ts +3 -0
- package/dist/node/contracts/index.js +4 -0
- package/dist/node/contracts/index.js.map +1 -0
- package/dist/node/contracts/nft.d.ts +76 -0
- package/dist/node/contracts/nft.js +329 -0
- package/dist/node/contracts/nft.js.map +1 -0
- package/dist/node/contracts.d.ts +709 -0
- package/dist/node/contracts.js +61 -0
- package/dist/node/contracts.js.map +1 -0
- package/dist/node/index.cjs +5032 -0
- package/dist/node/index.d.ts +8 -0
- package/dist/node/index.js +9 -0
- package/dist/node/index.js.map +1 -0
- package/dist/node/interfaces/admin.d.ts +102 -0
- package/dist/node/interfaces/admin.js +2 -0
- package/dist/node/interfaces/admin.js.map +1 -0
- package/dist/node/interfaces/approval.d.ts +57 -0
- package/dist/node/interfaces/approval.js +62 -0
- package/dist/node/interfaces/approval.js.map +1 -0
- package/dist/node/interfaces/collection.d.ts +57 -0
- package/dist/node/interfaces/collection.js +2 -0
- package/dist/node/interfaces/collection.js.map +1 -0
- package/dist/node/interfaces/encoding.d.ts +24 -0
- package/dist/node/interfaces/encoding.js +32 -0
- package/dist/node/interfaces/encoding.js.map +1 -0
- package/dist/node/interfaces/events.d.ts +833 -0
- package/dist/node/interfaces/events.js +106 -0
- package/dist/node/interfaces/events.js.map +1 -0
- package/dist/node/interfaces/index.d.ts +10 -0
- package/dist/node/interfaces/index.js +11 -0
- package/dist/node/interfaces/index.js.map +1 -0
- package/dist/node/interfaces/ownable.d.ts +94 -0
- package/dist/node/interfaces/ownable.js +12 -0
- package/dist/node/interfaces/ownable.js.map +1 -0
- package/dist/node/interfaces/owner.d.ts +61 -0
- package/dist/node/interfaces/owner.js +101 -0
- package/dist/node/interfaces/owner.js.map +1 -0
- package/dist/node/interfaces/pausable.d.ts +74 -0
- package/dist/node/interfaces/pausable.js +14 -0
- package/dist/node/interfaces/pausable.js.map +1 -0
- package/dist/node/interfaces/types.d.ts +2297 -0
- package/dist/node/interfaces/types.js +507 -0
- package/dist/node/interfaces/types.js.map +1 -0
- package/dist/node/interfaces/update.d.ts +53 -0
- package/dist/node/interfaces/update.js +58 -0
- package/dist/node/interfaces/update.js.map +1 -0
- package/dist/node/marketplace/auction.d.ts +775 -0
- package/dist/node/marketplace/auction.js +430 -0
- package/dist/node/marketplace/auction.js.map +1 -0
- package/dist/node/marketplace/bid.d.ts +254 -0
- package/dist/node/marketplace/bid.js +260 -0
- package/dist/node/marketplace/bid.js.map +1 -0
- package/dist/node/marketplace/index.d.ts +5 -0
- package/dist/node/marketplace/index.js +6 -0
- package/dist/node/marketplace/index.js.map +1 -0
- package/dist/node/marketplace/nft-shares.d.ts +1083 -0
- package/dist/node/marketplace/nft-shares.js +398 -0
- package/dist/node/marketplace/nft-shares.js.map +1 -0
- package/dist/node/marketplace/offer.d.ts +192 -0
- package/dist/node/marketplace/offer.js +132 -0
- package/dist/node/marketplace/offer.js.map +1 -0
- package/dist/node/marketplace/types.d.ts +374 -0
- package/dist/node/marketplace/types.js +33 -0
- package/dist/node/marketplace/types.js.map +1 -0
- package/dist/node/metadata/index.d.ts +3 -0
- package/dist/node/metadata/index.js +4 -0
- package/dist/node/metadata/index.js.map +1 -0
- package/dist/node/metadata/metadata.d.ts +337 -0
- package/dist/node/metadata/metadata.js +439 -0
- package/dist/node/metadata/metadata.js.map +1 -0
- package/dist/node/metadata/text.d.ts +44 -0
- package/dist/node/metadata/text.js +42 -0
- package/dist/node/metadata/text.js.map +1 -0
- package/dist/node/metadata/tree.d.ts +75 -0
- package/dist/node/metadata/tree.js +85 -0
- package/dist/node/metadata/tree.js.map +1 -0
- package/dist/node/vk.d.ts +42 -0
- package/dist/node/vk.js +45 -0
- package/dist/node/vk.js.map +1 -0
- package/dist/node/zkprogram-example/game.d.ts +76 -0
- package/dist/node/zkprogram-example/game.js +108 -0
- package/dist/node/zkprogram-example/game.js.map +1 -0
- package/dist/node/zkprogram-example/index.d.ts +2 -0
- package/dist/node/zkprogram-example/index.js +3 -0
- package/dist/node/zkprogram-example/index.js.map +1 -0
- package/dist/node/zkprogram-example/update.d.ts +76 -0
- package/dist/node/zkprogram-example/update.js +85 -0
- package/dist/node/zkprogram-example/update.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/tsconfig.web.tsbuildinfo +1 -0
- package/dist/web/admin/advanced.d.ts +469 -0
- package/dist/web/admin/advanced.js +525 -0
- package/dist/web/admin/advanced.js.map +1 -0
- package/dist/web/admin/index.d.ts +1 -0
- package/dist/web/admin/index.js +2 -0
- package/dist/web/admin/index.js.map +1 -0
- package/dist/web/contracts/admin.d.ts +140 -0
- package/dist/web/contracts/admin.js +336 -0
- package/dist/web/contracts/admin.js.map +1 -0
- package/dist/web/contracts/collection.d.ts +551 -0
- package/dist/web/contracts/collection.js +1049 -0
- package/dist/web/contracts/collection.js.map +1 -0
- package/dist/web/contracts/index.d.ts +3 -0
- package/dist/web/contracts/index.js +4 -0
- package/dist/web/contracts/index.js.map +1 -0
- package/dist/web/contracts/nft.d.ts +76 -0
- package/dist/web/contracts/nft.js +329 -0
- package/dist/web/contracts/nft.js.map +1 -0
- package/dist/web/contracts.d.ts +709 -0
- package/dist/web/contracts.js +61 -0
- package/dist/web/contracts.js.map +1 -0
- package/dist/web/index.d.ts +8 -0
- package/dist/web/index.js +9 -0
- package/dist/web/index.js.map +1 -0
- package/dist/web/interfaces/admin.d.ts +102 -0
- package/dist/web/interfaces/admin.js +2 -0
- package/dist/web/interfaces/admin.js.map +1 -0
- package/dist/web/interfaces/approval.d.ts +57 -0
- package/dist/web/interfaces/approval.js +62 -0
- package/dist/web/interfaces/approval.js.map +1 -0
- package/dist/web/interfaces/collection.d.ts +57 -0
- package/dist/web/interfaces/collection.js +2 -0
- package/dist/web/interfaces/collection.js.map +1 -0
- package/dist/web/interfaces/encoding.d.ts +24 -0
- package/dist/web/interfaces/encoding.js +32 -0
- package/dist/web/interfaces/encoding.js.map +1 -0
- package/dist/web/interfaces/events.d.ts +833 -0
- package/dist/web/interfaces/events.js +106 -0
- package/dist/web/interfaces/events.js.map +1 -0
- package/dist/web/interfaces/index.d.ts +10 -0
- package/dist/web/interfaces/index.js +11 -0
- package/dist/web/interfaces/index.js.map +1 -0
- package/dist/web/interfaces/ownable.d.ts +94 -0
- package/dist/web/interfaces/ownable.js +12 -0
- package/dist/web/interfaces/ownable.js.map +1 -0
- package/dist/web/interfaces/owner.d.ts +61 -0
- package/dist/web/interfaces/owner.js +101 -0
- package/dist/web/interfaces/owner.js.map +1 -0
- package/dist/web/interfaces/pausable.d.ts +74 -0
- package/dist/web/interfaces/pausable.js +14 -0
- package/dist/web/interfaces/pausable.js.map +1 -0
- package/dist/web/interfaces/types.d.ts +2297 -0
- package/dist/web/interfaces/types.js +507 -0
- package/dist/web/interfaces/types.js.map +1 -0
- package/dist/web/interfaces/update.d.ts +53 -0
- package/dist/web/interfaces/update.js +58 -0
- package/dist/web/interfaces/update.js.map +1 -0
- package/dist/web/marketplace/auction.d.ts +775 -0
- package/dist/web/marketplace/auction.js +430 -0
- package/dist/web/marketplace/auction.js.map +1 -0
- package/dist/web/marketplace/bid.d.ts +254 -0
- package/dist/web/marketplace/bid.js +260 -0
- package/dist/web/marketplace/bid.js.map +1 -0
- package/dist/web/marketplace/index.d.ts +5 -0
- package/dist/web/marketplace/index.js +6 -0
- package/dist/web/marketplace/index.js.map +1 -0
- package/dist/web/marketplace/nft-shares.d.ts +1083 -0
- package/dist/web/marketplace/nft-shares.js +398 -0
- package/dist/web/marketplace/nft-shares.js.map +1 -0
- package/dist/web/marketplace/offer.d.ts +192 -0
- package/dist/web/marketplace/offer.js +132 -0
- package/dist/web/marketplace/offer.js.map +1 -0
- package/dist/web/marketplace/types.d.ts +374 -0
- package/dist/web/marketplace/types.js +33 -0
- package/dist/web/marketplace/types.js.map +1 -0
- package/dist/web/metadata/index.d.ts +3 -0
- package/dist/web/metadata/index.js +4 -0
- package/dist/web/metadata/index.js.map +1 -0
- package/dist/web/metadata/metadata.d.ts +337 -0
- package/dist/web/metadata/metadata.js +439 -0
- package/dist/web/metadata/metadata.js.map +1 -0
- package/dist/web/metadata/text.d.ts +44 -0
- package/dist/web/metadata/text.js +42 -0
- package/dist/web/metadata/text.js.map +1 -0
- package/dist/web/metadata/tree.d.ts +75 -0
- package/dist/web/metadata/tree.js +85 -0
- package/dist/web/metadata/tree.js.map +1 -0
- package/dist/web/vk.d.ts +42 -0
- package/dist/web/vk.js +45 -0
- package/dist/web/vk.js.map +1 -0
- package/dist/web/zkprogram-example/game.d.ts +76 -0
- package/dist/web/zkprogram-example/game.js +108 -0
- package/dist/web/zkprogram-example/game.js.map +1 -0
- package/dist/web/zkprogram-example/index.d.ts +2 -0
- package/dist/web/zkprogram-example/index.js +3 -0
- package/dist/web/zkprogram-example/index.js.map +1 -0
- package/dist/web/zkprogram-example/update.d.ts +76 -0
- package/dist/web/zkprogram-example/update.js +85 -0
- package/dist/web/zkprogram-example/update.js.map +1 -0
- package/package.json +65 -0
- package/src/admin/advanced.ts +601 -0
- package/src/admin/index.ts +1 -0
- package/src/contracts/admin.ts +301 -0
- package/src/contracts/collection.ts +1172 -0
- package/src/contracts/index.ts +3 -0
- package/src/contracts/nft.ts +344 -0
- package/src/contracts.ts +107 -0
- package/src/index.ts +8 -0
- package/src/interfaces/admin.ts +127 -0
- package/src/interfaces/approval.ts +99 -0
- package/src/interfaces/collection.ts +68 -0
- package/src/interfaces/encoding.ts +32 -0
- package/src/interfaces/events.ts +115 -0
- package/src/interfaces/index.ts +10 -0
- package/src/interfaces/ownable.ts +32 -0
- package/src/interfaces/owner.ts +143 -0
- package/src/interfaces/pausable.ts +41 -0
- package/src/interfaces/types.ts +623 -0
- package/src/interfaces/update.ts +104 -0
- package/src/marketplace/auction.ts +527 -0
- package/src/marketplace/bid.ts +294 -0
- package/src/marketplace/index.ts +5 -0
- package/src/marketplace/nft-shares.ts +388 -0
- package/src/marketplace/offer.ts +153 -0
- package/src/marketplace/types.ts +33 -0
- package/src/metadata/index.ts +3 -0
- package/src/metadata/metadata.ts +603 -0
- package/src/metadata/text.ts +60 -0
- package/src/metadata/tree.ts +128 -0
- package/src/vk.ts +64 -0
- package/src/zkprogram-example/game.ts +136 -0
- package/src/zkprogram-example/index.ts +2 -0
- package/src/zkprogram-example/update.ts +98 -0
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountUpdate,
|
|
3
|
+
DeployArgs,
|
|
4
|
+
method,
|
|
5
|
+
Permissions,
|
|
6
|
+
PublicKey,
|
|
7
|
+
State,
|
|
8
|
+
state,
|
|
9
|
+
UInt64,
|
|
10
|
+
SmartContract,
|
|
11
|
+
Bool,
|
|
12
|
+
Field,
|
|
13
|
+
Struct,
|
|
14
|
+
Poseidon,
|
|
15
|
+
Provable,
|
|
16
|
+
} from "o1js";
|
|
17
|
+
import { Whitelist, OffChainList, Storage } from "@silvana-one/storage";
|
|
18
|
+
import {
|
|
19
|
+
NFTAddress,
|
|
20
|
+
SellEvent,
|
|
21
|
+
DepositEvent,
|
|
22
|
+
WithdrawEvent,
|
|
23
|
+
BidEvent,
|
|
24
|
+
} from "./types.js";
|
|
25
|
+
import {
|
|
26
|
+
NFTCollectionBase,
|
|
27
|
+
NFTCollectionContractConstructor,
|
|
28
|
+
TransferParams,
|
|
29
|
+
UInt64Option,
|
|
30
|
+
NFTTransactionContext,
|
|
31
|
+
} from "../interfaces/index.js";
|
|
32
|
+
|
|
33
|
+
export class Bid extends Struct({
|
|
34
|
+
price: UInt64,
|
|
35
|
+
points: UInt64,
|
|
36
|
+
}) {
|
|
37
|
+
pack() {
|
|
38
|
+
return Field.fromBits([
|
|
39
|
+
...this.price.value.toBits(64),
|
|
40
|
+
...this.points.value.toBits(64),
|
|
41
|
+
]);
|
|
42
|
+
}
|
|
43
|
+
static unpack(field: Field): Bid {
|
|
44
|
+
const bits = field.toBits(64 + 64);
|
|
45
|
+
const price = UInt64.Unsafe.fromField(Field.fromBits(bits.slice(0, 64)));
|
|
46
|
+
const points = UInt64.Unsafe.fromField(
|
|
47
|
+
Field.fromBits(bits.slice(64, 64 + 64))
|
|
48
|
+
);
|
|
49
|
+
return new Bid({
|
|
50
|
+
price,
|
|
51
|
+
points,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface NonFungibleTokenBidContractDeployProps
|
|
57
|
+
extends Exclude<DeployArgs, undefined> {
|
|
58
|
+
/** The whitelist. */
|
|
59
|
+
whitelist: Field;
|
|
60
|
+
/** The offers. */
|
|
61
|
+
bids: Field;
|
|
62
|
+
/** The storage. */
|
|
63
|
+
storage: Storage;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function BidFactory(params: {
|
|
67
|
+
collectionContract: () => NFTCollectionContractConstructor;
|
|
68
|
+
}) {
|
|
69
|
+
const { collectionContract } = params;
|
|
70
|
+
class NonFungibleTokenBidContract extends SmartContract {
|
|
71
|
+
@state(PublicKey) buyer = State<PublicKey>();
|
|
72
|
+
@state(Field) whitelist = State<Field>();
|
|
73
|
+
@state(Field) bids = State<Field>();
|
|
74
|
+
@state(Storage) storage = State<Storage>();
|
|
75
|
+
@state(UInt64) maxPoints = State<UInt64>();
|
|
76
|
+
// We do not have concurrency here, but given that it is a single-user contract,
|
|
77
|
+
// we can use state to track the points that have been consumed
|
|
78
|
+
// In case of concurrency, we can use the tokens to track the points
|
|
79
|
+
@state(UInt64) consumedPoints = State<UInt64>();
|
|
80
|
+
|
|
81
|
+
async deploy(args: NonFungibleTokenBidContractDeployProps) {
|
|
82
|
+
await super.deploy(args);
|
|
83
|
+
this.whitelist.set(args.whitelist);
|
|
84
|
+
this.bids.set(args.bids);
|
|
85
|
+
this.storage.set(args.storage);
|
|
86
|
+
this.account.permissions.set({
|
|
87
|
+
...Permissions.default(),
|
|
88
|
+
send: Permissions.proof(),
|
|
89
|
+
setVerificationKey:
|
|
90
|
+
Permissions.VerificationKey.impossibleDuringCurrentVersion(),
|
|
91
|
+
setPermissions: Permissions.impossible(),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
events = {
|
|
96
|
+
deposit: DepositEvent,
|
|
97
|
+
withdraw: WithdrawEvent,
|
|
98
|
+
sell: SellEvent,
|
|
99
|
+
updateWhitelist: Whitelist,
|
|
100
|
+
bid: BidEvent,
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
@method async initialize(amount: UInt64, maxPoints: UInt64) {
|
|
104
|
+
this.account.provedState.requireEquals(Bool(false));
|
|
105
|
+
|
|
106
|
+
const buyer = this.sender.getUnconstrained();
|
|
107
|
+
const buyerUpdate = AccountUpdate.createSigned(buyer);
|
|
108
|
+
// We use low-level subInPlace and addInPlace to decrease the number of AccountUpdates
|
|
109
|
+
buyerUpdate.balance.subInPlace(amount.add(UInt64.from(1_000_000_000)));
|
|
110
|
+
this.self.balance.addInPlace(amount);
|
|
111
|
+
buyerUpdate.body.useFullCommitment = Bool(true);
|
|
112
|
+
|
|
113
|
+
this.buyer.set(buyer);
|
|
114
|
+
this.maxPoints.set(maxPoints);
|
|
115
|
+
this.emitEvent(
|
|
116
|
+
"deposit",
|
|
117
|
+
new DepositEvent({
|
|
118
|
+
buyer,
|
|
119
|
+
amount,
|
|
120
|
+
maxPoints,
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
getCollectionContract(address: PublicKey): NFTCollectionBase {
|
|
126
|
+
const CollectionContract = collectionContract();
|
|
127
|
+
return new CollectionContract(address);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
@method async deposit(amount: UInt64, maxPoints: UInt64) {
|
|
131
|
+
amount.equals(UInt64.from(0)).assertFalse();
|
|
132
|
+
|
|
133
|
+
const sender = this.sender.getUnconstrained();
|
|
134
|
+
const buyer = this.buyer.getAndRequireEquals();
|
|
135
|
+
sender.assertEquals(buyer);
|
|
136
|
+
const buyerUpdate = AccountUpdate.createSigned(buyer);
|
|
137
|
+
buyerUpdate.send({ to: this.address, amount });
|
|
138
|
+
buyerUpdate.body.useFullCommitment = Bool(true);
|
|
139
|
+
|
|
140
|
+
this.maxPoints.set(maxPoints);
|
|
141
|
+
|
|
142
|
+
this.emitEvent(
|
|
143
|
+
"deposit",
|
|
144
|
+
new DepositEvent({
|
|
145
|
+
buyer,
|
|
146
|
+
amount,
|
|
147
|
+
maxPoints,
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@method async withdraw(amount: UInt64, maxPoints: UInt64) {
|
|
153
|
+
amount.equals(UInt64.from(0)).assertFalse();
|
|
154
|
+
this.account.balance.requireBetween(amount, UInt64.MAXINT());
|
|
155
|
+
|
|
156
|
+
const buyer = this.buyer.getAndRequireEquals();
|
|
157
|
+
const sender = this.sender.getUnconstrained();
|
|
158
|
+
const senderUpdate = AccountUpdate.createSigned(sender);
|
|
159
|
+
senderUpdate.body.useFullCommitment = Bool(true);
|
|
160
|
+
sender.assertEquals(buyer);
|
|
161
|
+
|
|
162
|
+
let bidUpdate = this.send({ to: senderUpdate, amount });
|
|
163
|
+
bidUpdate.body.useFullCommitment = Bool(true);
|
|
164
|
+
this.maxPoints.set(maxPoints);
|
|
165
|
+
this.emitEvent(
|
|
166
|
+
"withdraw",
|
|
167
|
+
new WithdrawEvent({
|
|
168
|
+
buyer,
|
|
169
|
+
amount,
|
|
170
|
+
maxPoints,
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@method async sell(nftAddress: NFTAddress, price: UInt64) {
|
|
176
|
+
await this._sell(nftAddress, price);
|
|
177
|
+
const buyer = this.buyer.getAndRequireEquals();
|
|
178
|
+
const Collection = collectionContract();
|
|
179
|
+
const collection = new Collection(nftAddress.collection);
|
|
180
|
+
await collection.transferBySignature(
|
|
181
|
+
new TransferParams({
|
|
182
|
+
address: nftAddress.nft,
|
|
183
|
+
from: PublicKey.empty(),
|
|
184
|
+
to: buyer,
|
|
185
|
+
price: UInt64Option.fromValue(price),
|
|
186
|
+
context: new NFTTransactionContext({
|
|
187
|
+
custom: [Field(0), Field(0), Field(0)],
|
|
188
|
+
}),
|
|
189
|
+
})
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
@method async approvedSell(nftAddress: NFTAddress, price: UInt64) {
|
|
194
|
+
await this._sell(nftAddress, price);
|
|
195
|
+
const buyer = this.buyer.getAndRequireEquals();
|
|
196
|
+
const Collection = collectionContract();
|
|
197
|
+
const collection = new Collection(nftAddress.collection);
|
|
198
|
+
await collection.approvedTransferBySignature(
|
|
199
|
+
new TransferParams({
|
|
200
|
+
address: nftAddress.nft,
|
|
201
|
+
from: PublicKey.empty(),
|
|
202
|
+
to: buyer,
|
|
203
|
+
price: UInt64Option.fromValue(price),
|
|
204
|
+
context: new NFTTransactionContext({
|
|
205
|
+
custom: [Field(0), Field(0), Field(0)],
|
|
206
|
+
}),
|
|
207
|
+
})
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async _sell(nftAddress: NFTAddress, price: UInt64) {
|
|
212
|
+
price.equals(UInt64.from(0)).assertFalse();
|
|
213
|
+
const key = Poseidon.hashPacked(NFTAddress, nftAddress);
|
|
214
|
+
const storage = this.storage.getAndRequireEquals();
|
|
215
|
+
const bids = new OffChainList({
|
|
216
|
+
root: this.bids.getAndRequireEquals(),
|
|
217
|
+
storage,
|
|
218
|
+
});
|
|
219
|
+
const bid = Bid.unpack(
|
|
220
|
+
(await bids.getValue(key, "bids")).assertSome("bid not found")
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
// We do not require the price to be equal to the bid price,
|
|
224
|
+
// because the price can be lower than the bid price
|
|
225
|
+
// and the seller can still be willing to sell the NFT
|
|
226
|
+
// as the deposit remaining is less than bid price
|
|
227
|
+
price.assertLessThanOrEqual(bid.price, "price is too high");
|
|
228
|
+
this.account.balance.requireBetween(price, UInt64.MAXINT());
|
|
229
|
+
|
|
230
|
+
const consumedPoints = this.consumedPoints.getAndRequireEquals();
|
|
231
|
+
const maxPoints = this.maxPoints.getAndRequireEquals();
|
|
232
|
+
const newConsumedPoints = consumedPoints.add(bid.points);
|
|
233
|
+
newConsumedPoints.assertLessThanOrEqual(
|
|
234
|
+
maxPoints,
|
|
235
|
+
"consumed points exceed max points"
|
|
236
|
+
);
|
|
237
|
+
this.consumedPoints.set(newConsumedPoints);
|
|
238
|
+
|
|
239
|
+
const seller = this.sender.getUnconstrained();
|
|
240
|
+
const sellerUpdate = AccountUpdate.createSigned(seller);
|
|
241
|
+
sellerUpdate.balance.addInPlace(price);
|
|
242
|
+
this.self.balance.subInPlace(price);
|
|
243
|
+
sellerUpdate.body.useFullCommitment = Bool(true);
|
|
244
|
+
|
|
245
|
+
const whitelist = new Whitelist({
|
|
246
|
+
list: new OffChainList({
|
|
247
|
+
root: this.whitelist.getAndRequireEquals(),
|
|
248
|
+
storage,
|
|
249
|
+
}),
|
|
250
|
+
});
|
|
251
|
+
const whitelistedAmount = await whitelist.getWhitelistedAmount(
|
|
252
|
+
seller,
|
|
253
|
+
"whitelist"
|
|
254
|
+
);
|
|
255
|
+
const whitelistDisabled = whitelist.isNone();
|
|
256
|
+
whitelistedAmount.isSome
|
|
257
|
+
.or(whitelistDisabled)
|
|
258
|
+
.assertTrue("Cannot buy from non-whitelisted address");
|
|
259
|
+
const maxPrice = Provable.if(
|
|
260
|
+
whitelistDisabled,
|
|
261
|
+
UInt64.MAXINT(),
|
|
262
|
+
whitelistedAmount.value
|
|
263
|
+
);
|
|
264
|
+
price.assertLessThanOrEqual(
|
|
265
|
+
maxPrice,
|
|
266
|
+
"price is higher than whitelisted price"
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
this.emitEvent(
|
|
270
|
+
"sell",
|
|
271
|
+
new SellEvent({
|
|
272
|
+
collection: nftAddress.collection,
|
|
273
|
+
nft: nftAddress.nft,
|
|
274
|
+
price,
|
|
275
|
+
})
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
@method async bid(bids: Field, whitelist: Field, storage: Storage) {
|
|
280
|
+
const buyer = this.buyer.getAndRequireEquals();
|
|
281
|
+
const sender = this.sender.getUnconstrained();
|
|
282
|
+
const senderUpdate = AccountUpdate.createSigned(sender);
|
|
283
|
+
senderUpdate.body.useFullCommitment = Bool(true);
|
|
284
|
+
sender.assertEquals(buyer);
|
|
285
|
+
|
|
286
|
+
this.bids.set(bids);
|
|
287
|
+
this.whitelist.set(whitelist);
|
|
288
|
+
this.storage.set(storage);
|
|
289
|
+
this.emitEvent("bid", new BidEvent({ bids, whitelist, storage }));
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
return NonFungibleTokenBidContract;
|
|
294
|
+
}
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountUpdate,
|
|
3
|
+
Bool,
|
|
4
|
+
DeployArgs,
|
|
5
|
+
method,
|
|
6
|
+
Permissions,
|
|
7
|
+
PublicKey,
|
|
8
|
+
SmartContract,
|
|
9
|
+
State,
|
|
10
|
+
state,
|
|
11
|
+
VerificationKey,
|
|
12
|
+
UInt64,
|
|
13
|
+
Field,
|
|
14
|
+
Struct,
|
|
15
|
+
Provable,
|
|
16
|
+
TokenId,
|
|
17
|
+
} from "o1js";
|
|
18
|
+
import {
|
|
19
|
+
FungibleTokenAdminBase,
|
|
20
|
+
FungibleTokenContract,
|
|
21
|
+
} from "@silvana-one/token";
|
|
22
|
+
import { NFTOwnerBase, TransferExtendedParams } from "../interfaces/index.js";
|
|
23
|
+
import { Auction, AuctionFactory } from "./auction.js";
|
|
24
|
+
|
|
25
|
+
export interface NFTSharesAdminDeployProps
|
|
26
|
+
extends Exclude<DeployArgs, undefined> {
|
|
27
|
+
admin: PublicKey;
|
|
28
|
+
owner: PublicKey; // The owner of the NFT
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface NFTSharesOwnerDeployProps
|
|
32
|
+
extends Exclude<DeployArgs, undefined> {
|
|
33
|
+
admin: PublicKey;
|
|
34
|
+
owner: PublicKey;
|
|
35
|
+
collection: PublicKey;
|
|
36
|
+
nft: PublicKey;
|
|
37
|
+
auction: PublicKey;
|
|
38
|
+
maxBuyPrice: UInt64;
|
|
39
|
+
minSellPrice: UInt64;
|
|
40
|
+
uri: string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class NFTSharesDataPacked extends Struct({
|
|
44
|
+
adminX: Field,
|
|
45
|
+
ownerX: Field,
|
|
46
|
+
collectionX: Field,
|
|
47
|
+
nftX: Field,
|
|
48
|
+
auctionX: Field,
|
|
49
|
+
data: Field,
|
|
50
|
+
}) {}
|
|
51
|
+
|
|
52
|
+
export class NFTSharesData extends Struct({
|
|
53
|
+
admin: PublicKey,
|
|
54
|
+
owner: PublicKey,
|
|
55
|
+
collection: PublicKey,
|
|
56
|
+
nft: PublicKey,
|
|
57
|
+
auction: PublicKey,
|
|
58
|
+
maxBuyPrice: UInt64,
|
|
59
|
+
minSellPrice: UInt64,
|
|
60
|
+
}) {
|
|
61
|
+
pack(): NFTSharesDataPacked {
|
|
62
|
+
const data = Field.fromBits([
|
|
63
|
+
...this.maxBuyPrice.value.toBits(64),
|
|
64
|
+
...this.minSellPrice.value.toBits(64),
|
|
65
|
+
this.admin.isOdd,
|
|
66
|
+
this.owner.isOdd,
|
|
67
|
+
this.collection.isOdd,
|
|
68
|
+
this.nft.isOdd,
|
|
69
|
+
this.auction.isOdd,
|
|
70
|
+
]);
|
|
71
|
+
return new NFTSharesDataPacked({
|
|
72
|
+
adminX: this.admin.x,
|
|
73
|
+
ownerX: this.owner.x,
|
|
74
|
+
collectionX: this.collection.x,
|
|
75
|
+
nftX: this.nft.x,
|
|
76
|
+
auctionX: this.auction.x,
|
|
77
|
+
data,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
static unpack(packed: NFTSharesDataPacked): NFTSharesData {
|
|
81
|
+
const bits = packed.data.toBits(64 + 64 + 5);
|
|
82
|
+
const adminIsOdd = bits[64 + 64];
|
|
83
|
+
const ownerIsOdd = bits[64 + 64 + 1];
|
|
84
|
+
const collectionIsOdd = bits[64 + 64 + 2];
|
|
85
|
+
const nftIsOdd = bits[64 + 64 + 3];
|
|
86
|
+
const auctionIsOdd = bits[64 + 64 + 4];
|
|
87
|
+
const adminX = packed.adminX;
|
|
88
|
+
const ownerX = packed.ownerX;
|
|
89
|
+
const collectionX = packed.collectionX;
|
|
90
|
+
const nftX = packed.nftX;
|
|
91
|
+
const auctionX = packed.auctionX;
|
|
92
|
+
const admin = PublicKey.from({ x: adminX, isOdd: adminIsOdd });
|
|
93
|
+
const owner = PublicKey.from({ x: ownerX, isOdd: ownerIsOdd });
|
|
94
|
+
const collection = PublicKey.from({
|
|
95
|
+
x: collectionX,
|
|
96
|
+
isOdd: collectionIsOdd,
|
|
97
|
+
});
|
|
98
|
+
const nft = PublicKey.from({ x: nftX, isOdd: nftIsOdd });
|
|
99
|
+
const auction = PublicKey.from({ x: auctionX, isOdd: auctionIsOdd });
|
|
100
|
+
const maxBuyPrice = UInt64.Unsafe.fromField(
|
|
101
|
+
Field.fromBits(bits.slice(0, 64))
|
|
102
|
+
);
|
|
103
|
+
const minSellPrice = UInt64.Unsafe.fromField(
|
|
104
|
+
Field.fromBits(bits.slice(64, 64 + 64))
|
|
105
|
+
);
|
|
106
|
+
return new NFTSharesData({
|
|
107
|
+
admin,
|
|
108
|
+
owner,
|
|
109
|
+
collection,
|
|
110
|
+
nft,
|
|
111
|
+
auction,
|
|
112
|
+
maxBuyPrice,
|
|
113
|
+
minSellPrice,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export type DefineNFTSharesFactory = (params: {
|
|
119
|
+
auctionContract: () => ReturnType<typeof AuctionFactory>;
|
|
120
|
+
}) => ReturnType<typeof NFTSharesFactory>;
|
|
121
|
+
|
|
122
|
+
export function NFTSharesFactory(params: {
|
|
123
|
+
auctionContract: () => ReturnType<typeof AuctionFactory>;
|
|
124
|
+
}) {
|
|
125
|
+
const { auctionContract } = params;
|
|
126
|
+
|
|
127
|
+
class NFTSharesAdmin extends SmartContract implements FungibleTokenAdminBase {
|
|
128
|
+
@state(PublicKey) admin = State<PublicKey>();
|
|
129
|
+
@state(PublicKey) owner = State<PublicKey>();
|
|
130
|
+
|
|
131
|
+
async deploy(props: NFTSharesAdminDeployProps) {
|
|
132
|
+
await super.deploy(props);
|
|
133
|
+
this.admin.set(props.admin);
|
|
134
|
+
this.owner.set(props.owner);
|
|
135
|
+
this.account.permissions.set({
|
|
136
|
+
...Permissions.default(),
|
|
137
|
+
setVerificationKey:
|
|
138
|
+
Permissions.VerificationKey.proofDuringCurrentVersion(),
|
|
139
|
+
setPermissions: Permissions.impossible(),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
@method
|
|
144
|
+
async updateVerificationKey(vk: VerificationKey) {
|
|
145
|
+
this.ensureAdminSignature();
|
|
146
|
+
this.account.verificationKey.set(vk);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
ensureAdminSignature(): AccountUpdate {
|
|
150
|
+
const admin = this.admin.getAndRequireEquals();
|
|
151
|
+
return AccountUpdate.createSigned(admin);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
getOwner(): NFTSharesOwner {
|
|
155
|
+
return new NFTSharesOwner(this.owner.getAndRequireEquals());
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
@method.returns(Bool)
|
|
159
|
+
public async canMint(_accountUpdate: AccountUpdate) {
|
|
160
|
+
const owner = this.getOwner();
|
|
161
|
+
return await owner.canMint(_accountUpdate);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
@method.returns(Bool)
|
|
165
|
+
public async canChangeAdmin(_admin: PublicKey) {
|
|
166
|
+
this.ensureAdminSignature();
|
|
167
|
+
return Bool(true);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@method.returns(Bool)
|
|
171
|
+
public async canPause(): Promise<Bool> {
|
|
172
|
+
this.ensureAdminSignature();
|
|
173
|
+
return Bool(true);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@method.returns(Bool)
|
|
177
|
+
public async canResume(): Promise<Bool> {
|
|
178
|
+
this.ensureAdminSignature();
|
|
179
|
+
return Bool(true);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@method.returns(Bool)
|
|
183
|
+
public async canChangeVerificationKey(_vk: VerificationKey): Promise<Bool> {
|
|
184
|
+
this.ensureAdminSignature();
|
|
185
|
+
return Bool(true);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const FungibleToken = FungibleTokenContract(NFTSharesAdmin);
|
|
190
|
+
|
|
191
|
+
class NFTSharesOwner extends SmartContract implements NFTOwnerBase {
|
|
192
|
+
/**
|
|
193
|
+
* The public key of the contract's administrator.
|
|
194
|
+
* This account has the authority to perform administrative actions such as pausing the contract or upgrading the verification key.
|
|
195
|
+
*/
|
|
196
|
+
@state(NFTSharesDataPacked) data = State<NFTSharesDataPacked>(); // FungibleTokenAdmin
|
|
197
|
+
@state(Bool) subscriptionOpen = State<Bool>(Bool(true));
|
|
198
|
+
@state(UInt64) sharesOutstanding = State<UInt64>(UInt64.zero);
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Deploys the contract with initial settings.
|
|
202
|
+
* @param props - Deployment properties including admin, upgradeAuthority, uri, canPause, and isPaused.
|
|
203
|
+
*/
|
|
204
|
+
async deploy(props: NFTSharesOwnerDeployProps) {
|
|
205
|
+
await super.deploy(props);
|
|
206
|
+
this.data.set(
|
|
207
|
+
new NFTSharesData({
|
|
208
|
+
admin: props.admin,
|
|
209
|
+
owner: props.owner,
|
|
210
|
+
collection: props.collection,
|
|
211
|
+
nft: props.nft,
|
|
212
|
+
auction: props.auction,
|
|
213
|
+
maxBuyPrice: props.maxBuyPrice,
|
|
214
|
+
minSellPrice: props.minSellPrice,
|
|
215
|
+
}).pack()
|
|
216
|
+
);
|
|
217
|
+
this.account.zkappUri.set(props.uri);
|
|
218
|
+
this.subscriptionOpen.set(Bool(true));
|
|
219
|
+
this.sharesOutstanding.set(UInt64.zero);
|
|
220
|
+
this.account.permissions.set({
|
|
221
|
+
...Permissions.default(),
|
|
222
|
+
// Allow the upgrade authority to set the verification key even without a protocol upgrade,
|
|
223
|
+
// enabling upgrades in case of o1js breaking changes.
|
|
224
|
+
setVerificationKey:
|
|
225
|
+
Permissions.VerificationKey.proofDuringCurrentVersion(),
|
|
226
|
+
setPermissions: Permissions.impossible(),
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Ensures that the transaction is authorized by the contract owner.
|
|
232
|
+
* @returns A signed `AccountUpdate` from the admin.
|
|
233
|
+
*/
|
|
234
|
+
ensureOwnerSignature(): NFTSharesData {
|
|
235
|
+
const data = NFTSharesData.unpack(this.data.getAndRequireEquals());
|
|
236
|
+
const adminUpdate = AccountUpdate.createSigned(data.admin);
|
|
237
|
+
adminUpdate.body.useFullCommitment = Bool(true); // Prevent memo and fee change
|
|
238
|
+
return data;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
getAuction(auction: PublicKey) {
|
|
242
|
+
return new (auctionContract())(auction);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Allows the owner to mint shares.
|
|
246
|
+
* This method should NOT called directly, but through the FungibleToken.mint()
|
|
247
|
+
*
|
|
248
|
+
* @param _accountUpdate - The account update containing the sender's information.
|
|
249
|
+
* @returns A boolean indicating if the minting is allowed.
|
|
250
|
+
*/
|
|
251
|
+
@method.returns(Bool)
|
|
252
|
+
async canMint(_accountUpdate: AccountUpdate): Promise<Bool> {
|
|
253
|
+
const subscriptionOpen = this.subscriptionOpen.getAndRequireEquals();
|
|
254
|
+
subscriptionOpen.assertEquals(Bool(true), "Subscription is closed");
|
|
255
|
+
const address = _accountUpdate.publicKey;
|
|
256
|
+
const amount = _accountUpdate.balanceChange.magnitude;
|
|
257
|
+
const senderUpdate = AccountUpdate.createSigned(address);
|
|
258
|
+
// 1 share = 1 MINA
|
|
259
|
+
senderUpdate.balance.subInPlace(amount);
|
|
260
|
+
this.balance.addInPlace(amount);
|
|
261
|
+
const sharesOutstanding = this.sharesOutstanding.getAndRequireEquals();
|
|
262
|
+
this.sharesOutstanding.set(sharesOutstanding.add(amount));
|
|
263
|
+
return Bool(true);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
@method
|
|
267
|
+
async withdraw(shares: UInt64) {
|
|
268
|
+
const subscriptionOpen = this.subscriptionOpen.getAndRequireEquals();
|
|
269
|
+
subscriptionOpen.assertEquals(
|
|
270
|
+
Bool(false),
|
|
271
|
+
"Subscription is not closed, cannot withdraw"
|
|
272
|
+
);
|
|
273
|
+
const sharesOutstanding = this.sharesOutstanding.getAndRequireEquals();
|
|
274
|
+
const balance = this.account.balance.getAndRequireEquals();
|
|
275
|
+
balance
|
|
276
|
+
.equals(UInt64.zero)
|
|
277
|
+
.assertFalse("Balance is zero, nothing to withdraw");
|
|
278
|
+
const amountInMinaField = shares.value
|
|
279
|
+
.mul(balance.value)
|
|
280
|
+
.div(sharesOutstanding.value);
|
|
281
|
+
amountInMinaField.assertLessThanOrEqual(
|
|
282
|
+
balance.value,
|
|
283
|
+
"Amount in Mina is greater than the balance"
|
|
284
|
+
);
|
|
285
|
+
const amountInMina = UInt64.Unsafe.fromField(amountInMinaField);
|
|
286
|
+
const sender = this.sender.getUnconstrained();
|
|
287
|
+
const senderUpdate = AccountUpdate.createSigned(sender);
|
|
288
|
+
senderUpdate.balance.addInPlace(amountInMina);
|
|
289
|
+
this.balance.subInPlace(amountInMina);
|
|
290
|
+
senderUpdate.body.useFullCommitment = Bool(true);
|
|
291
|
+
this.sharesOutstanding.set(sharesOutstanding.sub(shares));
|
|
292
|
+
const data = NFTSharesData.unpack(this.data.getAndRequireEquals());
|
|
293
|
+
const token = new FungibleToken(data.owner);
|
|
294
|
+
await token.burn(sender, shares);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
@method
|
|
298
|
+
async closeSubscription() {
|
|
299
|
+
const data = this.ensureOwnerSignature();
|
|
300
|
+
const maxBuyPrice = data.maxBuyPrice;
|
|
301
|
+
this.account.balance.requireBetween(maxBuyPrice, UInt64.MAXINT());
|
|
302
|
+
this.subscriptionOpen.set(Bool(false));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
@method
|
|
306
|
+
async bid(price: UInt64) {
|
|
307
|
+
const data = NFTSharesData.unpack(this.data.getAndRequireEquals());
|
|
308
|
+
const maxBuyPrice = data.maxBuyPrice;
|
|
309
|
+
price.assertLessThanOrEqual(maxBuyPrice, "Price is too high");
|
|
310
|
+
this.account.balance.requireBetween(price, UInt64.MAXINT());
|
|
311
|
+
this.subscriptionOpen.set(Bool(false));
|
|
312
|
+
const sharesOutstanding = this.sharesOutstanding.getAndRequireEquals();
|
|
313
|
+
const auction = this.getAuction(data.auction);
|
|
314
|
+
const sender = this.sender.getUnconstrained();
|
|
315
|
+
const senderUpdate = AccountUpdate.createSigned(sender);
|
|
316
|
+
const tokenId = TokenId.derive(data.owner);
|
|
317
|
+
const tokenUpdate = AccountUpdate.create(sender, tokenId);
|
|
318
|
+
const tokenBalance = tokenUpdate.account.balance.getAndRequireEquals();
|
|
319
|
+
const token = new FungibleToken(data.owner);
|
|
320
|
+
await token.approveAccountUpdate(tokenUpdate);
|
|
321
|
+
|
|
322
|
+
tokenBalance
|
|
323
|
+
.mul(4)
|
|
324
|
+
.assertGreaterThanOrEqual(
|
|
325
|
+
sharesOutstanding,
|
|
326
|
+
"Not enough shares to bid, minimum is 25% of the shares outstanding"
|
|
327
|
+
);
|
|
328
|
+
|
|
329
|
+
senderUpdate.balance.addInPlace(price);
|
|
330
|
+
this.balance.subInPlace(price);
|
|
331
|
+
senderUpdate.body.useFullCommitment = Bool(true);
|
|
332
|
+
await auction.bid(price, this.address);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
@method.returns(Bool)
|
|
336
|
+
async canTransfer(params: TransferExtendedParams): Promise<Bool> {
|
|
337
|
+
const data = NFTSharesData.unpack(this.data.getAndRequireEquals());
|
|
338
|
+
params.collection.assertEquals(data.collection);
|
|
339
|
+
params.nft.assertEquals(data.nft);
|
|
340
|
+
const amount = params.price.assertSome();
|
|
341
|
+
amount.assertGreaterThanOrEqual(data.minSellPrice, "Price is too low");
|
|
342
|
+
const sender = this.sender.getUnconstrained();
|
|
343
|
+
const senderUpdate = AccountUpdate.createSigned(sender);
|
|
344
|
+
senderUpdate.balance.subInPlace(amount);
|
|
345
|
+
senderUpdate.body.useFullCommitment = Bool(true);
|
|
346
|
+
this.balance.addInPlace(amount);
|
|
347
|
+
return Bool(true);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
@method.returns(Bool)
|
|
351
|
+
async canPause(collection: PublicKey, nft: PublicKey): Promise<Bool> {
|
|
352
|
+
this.ensureOwnerSignature();
|
|
353
|
+
return Bool(true);
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
@method.returns(Bool)
|
|
357
|
+
async canResume(collection: PublicKey, nft: PublicKey): Promise<Bool> {
|
|
358
|
+
this.ensureOwnerSignature();
|
|
359
|
+
return Bool(true);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
@method.returns(Bool)
|
|
363
|
+
async canChangeVerificationKey(
|
|
364
|
+
collection: PublicKey,
|
|
365
|
+
nft: PublicKey,
|
|
366
|
+
vk: VerificationKey
|
|
367
|
+
): Promise<Bool> {
|
|
368
|
+
this.ensureOwnerSignature();
|
|
369
|
+
return Bool(true);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
@method.returns(Bool)
|
|
373
|
+
async canApproveAddress(
|
|
374
|
+
collection: PublicKey,
|
|
375
|
+
nft: PublicKey,
|
|
376
|
+
approved: PublicKey
|
|
377
|
+
): Promise<Bool> {
|
|
378
|
+
this.ensureOwnerSignature();
|
|
379
|
+
return Bool(true);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
NFTSharesAdmin,
|
|
385
|
+
NFTSharesOwner,
|
|
386
|
+
FungibleToken,
|
|
387
|
+
};
|
|
388
|
+
}
|