@haneullabs/zksend 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/CHANGELOG.md +1084 -0
- package/README.md +1 -0
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.js +38 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/index.test.d.ts +4 -0
- package/dist/cjs/links/builder.d.ts +55 -0
- package/dist/cjs/links/builder.js +361 -0
- package/dist/cjs/links/builder.js.map +7 -0
- package/dist/cjs/links/claim.d.ts +57 -0
- package/dist/cjs/links/claim.js +573 -0
- package/dist/cjs/links/claim.js.map +7 -0
- package/dist/cjs/links/get-sent-transactions.d.ts +25 -0
- package/dist/cjs/links/get-sent-transactions.js +134 -0
- package/dist/cjs/links/get-sent-transactions.js.map +7 -0
- package/dist/cjs/links/list-created-links.d.ts +24 -0
- package/dist/cjs/links/list-created-links.js +124 -0
- package/dist/cjs/links/list-created-links.js.map +7 -0
- package/dist/cjs/links/utils.d.ts +34 -0
- package/dist/cjs/links/utils.js +132 -0
- package/dist/cjs/links/utils.js.map +7 -0
- package/dist/cjs/links/zk-bag.d.ts +72 -0
- package/dist/cjs/links/zk-bag.js +145 -0
- package/dist/cjs/links/zk-bag.js.map +7 -0
- package/dist/cjs/package.json +5 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +20 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/index.test.d.ts +4 -0
- package/dist/esm/links/builder.d.ts +55 -0
- package/dist/esm/links/builder.js +341 -0
- package/dist/esm/links/builder.js.map +7 -0
- package/dist/esm/links/claim.d.ts +57 -0
- package/dist/esm/links/claim.js +561 -0
- package/dist/esm/links/claim.js.map +7 -0
- package/dist/esm/links/get-sent-transactions.d.ts +25 -0
- package/dist/esm/links/get-sent-transactions.js +114 -0
- package/dist/esm/links/get-sent-transactions.js.map +7 -0
- package/dist/esm/links/list-created-links.d.ts +24 -0
- package/dist/esm/links/list-created-links.js +104 -0
- package/dist/esm/links/list-created-links.js.map +7 -0
- package/dist/esm/links/utils.d.ts +34 -0
- package/dist/esm/links/utils.js +112 -0
- package/dist/esm/links/utils.js.map +7 -0
- package/dist/esm/links/zk-bag.d.ts +72 -0
- package/dist/esm/links/zk-bag.js +125 -0
- package/dist/esm/links/zk-bag.js.map +7 -0
- package/dist/esm/package.json +5 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/experimental/unified-adapter/package.json +6 -0
- package/package.json +60 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { HaneulClient } from '@haneullabs/haneul/client';
|
|
2
|
+
import type { HaneulObjectData, HaneulTransactionBlockResponse } from '@haneullabs/haneul/client';
|
|
3
|
+
import type { Keypair } from '@haneullabs/haneul/cryptography';
|
|
4
|
+
import { Transaction } from '@haneullabs/haneul/transactions';
|
|
5
|
+
import type { ZkSendLinkBuilderOptions } from './builder.js';
|
|
6
|
+
import type { LinkAssets } from './utils.js';
|
|
7
|
+
import type { ZkBagContractOptions } from './zk-bag.js';
|
|
8
|
+
export type ZkSendLinkOptions = {
|
|
9
|
+
claimApi?: string;
|
|
10
|
+
keypair?: Keypair;
|
|
11
|
+
client?: HaneulClient;
|
|
12
|
+
network?: 'mainnet' | 'testnet';
|
|
13
|
+
host?: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
address?: string;
|
|
16
|
+
isContractLink: boolean;
|
|
17
|
+
contract?: ZkBagContractOptions | null;
|
|
18
|
+
} & ({
|
|
19
|
+
address: string;
|
|
20
|
+
keypair?: never;
|
|
21
|
+
} | {
|
|
22
|
+
keypair: Keypair;
|
|
23
|
+
address?: never;
|
|
24
|
+
});
|
|
25
|
+
export declare class ZkSendLink {
|
|
26
|
+
#private;
|
|
27
|
+
address: string;
|
|
28
|
+
keypair?: Keypair;
|
|
29
|
+
creatorAddress?: string;
|
|
30
|
+
assets?: LinkAssets;
|
|
31
|
+
claimed?: boolean;
|
|
32
|
+
claimedBy?: string;
|
|
33
|
+
bagObject?: HaneulObjectData | null;
|
|
34
|
+
constructor({ network, client, keypair, contract, address, host, path, claimApi, isContractLink, }: ZkSendLinkOptions);
|
|
35
|
+
static fromUrl(url: string, options?: Omit<ZkSendLinkOptions, 'keypair' | 'address' | 'isContractLink'>): Promise<ZkSendLink>;
|
|
36
|
+
static fromAddress(address: string, options: Omit<ZkSendLinkOptions, 'keypair' | 'address' | 'isContractLink'>): Promise<ZkSendLink>;
|
|
37
|
+
loadClaimedStatus(): Promise<void>;
|
|
38
|
+
loadAssets(options?: {
|
|
39
|
+
transaction?: HaneulTransactionBlockResponse;
|
|
40
|
+
loadAssets?: boolean;
|
|
41
|
+
loadClaimedAssets?: boolean;
|
|
42
|
+
}): Promise<void>;
|
|
43
|
+
claimAssets(address: string, { reclaim, sign, }?: {
|
|
44
|
+
reclaim?: false;
|
|
45
|
+
sign?: never;
|
|
46
|
+
} | {
|
|
47
|
+
reclaim: true;
|
|
48
|
+
sign: (transaction: Uint8Array) => Promise<string>;
|
|
49
|
+
}): Promise<HaneulTransactionBlockResponse>;
|
|
50
|
+
createClaimTransaction(address: string, { reclaim, }?: {
|
|
51
|
+
reclaim?: boolean;
|
|
52
|
+
}): Transaction;
|
|
53
|
+
createRegenerateTransaction(sender: string, options?: Omit<ZkSendLinkBuilderOptions, 'sender'>): Promise<{
|
|
54
|
+
url: string;
|
|
55
|
+
transaction: Transaction;
|
|
56
|
+
}>;
|
|
57
|
+
}
|
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
var __typeError = (msg) => {
|
|
2
|
+
throw TypeError(msg);
|
|
3
|
+
};
|
|
4
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
5
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
6
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
7
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
8
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
9
|
+
var _client, _contract, _network, _host, _path, _claimApi, _gasCoin, _hasSui, _ownedObjects, _ZkSendLink_instances, loadBagObject_fn, loadBag_fn, loadClaimedAssets_fn, createSponsoredTransaction_fn, executeSponsoredTransaction_fn, fetch_fn, listNonContractClaimableAssets_fn, createNonContractClaimTransaction_fn, loadOwnedObjects_fn;
|
|
10
|
+
import { bcs } from "@haneullabs/haneul/bcs";
|
|
11
|
+
import { getFullnodeUrl, HaneulClient } from "@haneullabs/haneul/client";
|
|
12
|
+
import { Ed25519Keypair } from "@haneullabs/haneul/keypairs/ed25519";
|
|
13
|
+
import { Transaction } from "@haneullabs/haneul/transactions";
|
|
14
|
+
import {
|
|
15
|
+
fromBase64,
|
|
16
|
+
normalizeStructTag,
|
|
17
|
+
normalizeHaneulAddress,
|
|
18
|
+
normalizeHaneulObjectId,
|
|
19
|
+
parseStructTag,
|
|
20
|
+
HANEUL_TYPE_ARG,
|
|
21
|
+
toBase64
|
|
22
|
+
} from "@haneullabs/haneul/utils";
|
|
23
|
+
import { ZkSendLinkBuilder } from "./builder.js";
|
|
24
|
+
import { getAssetsFromTransaction, isOwner, ownedAfterChange } from "./utils.js";
|
|
25
|
+
import { getContractIds, ZkBag } from "./zk-bag.js";
|
|
26
|
+
const DEFAULT_ZK_SEND_LINK_OPTIONS = {
|
|
27
|
+
host: "https://api.slush.app",
|
|
28
|
+
path: "/claim",
|
|
29
|
+
network: "mainnet"
|
|
30
|
+
};
|
|
31
|
+
const HANEUL_COIN_TYPE = normalizeStructTag(HANEUL_TYPE_ARG);
|
|
32
|
+
const HANEUL_COIN_OBJECT_TYPE = normalizeStructTag("0x2::coin::Coin<0x2::haneul::HANEUL>");
|
|
33
|
+
const _ZkSendLink = class _ZkSendLink {
|
|
34
|
+
constructor({
|
|
35
|
+
network = DEFAULT_ZK_SEND_LINK_OPTIONS.network,
|
|
36
|
+
client = new HaneulClient({ url: getFullnodeUrl(network) }),
|
|
37
|
+
keypair,
|
|
38
|
+
contract = getContractIds(network),
|
|
39
|
+
address,
|
|
40
|
+
host = DEFAULT_ZK_SEND_LINK_OPTIONS.host,
|
|
41
|
+
path = DEFAULT_ZK_SEND_LINK_OPTIONS.path,
|
|
42
|
+
claimApi = `${host}/api`,
|
|
43
|
+
isContractLink
|
|
44
|
+
}) {
|
|
45
|
+
__privateAdd(this, _ZkSendLink_instances);
|
|
46
|
+
__privateAdd(this, _client);
|
|
47
|
+
__privateAdd(this, _contract);
|
|
48
|
+
__privateAdd(this, _network);
|
|
49
|
+
__privateAdd(this, _host);
|
|
50
|
+
__privateAdd(this, _path);
|
|
51
|
+
__privateAdd(this, _claimApi);
|
|
52
|
+
// State for non-contract based links
|
|
53
|
+
__privateAdd(this, _gasCoin);
|
|
54
|
+
__privateAdd(this, _hasSui, false);
|
|
55
|
+
__privateAdd(this, _ownedObjects, []);
|
|
56
|
+
if (!keypair && !address) {
|
|
57
|
+
throw new Error("Either keypair or address must be provided");
|
|
58
|
+
}
|
|
59
|
+
__privateSet(this, _client, client);
|
|
60
|
+
this.keypair = keypair;
|
|
61
|
+
this.address = address ?? keypair.toHaneulAddress();
|
|
62
|
+
__privateSet(this, _claimApi, claimApi);
|
|
63
|
+
__privateSet(this, _network, network);
|
|
64
|
+
__privateSet(this, _host, host);
|
|
65
|
+
__privateSet(this, _path, path);
|
|
66
|
+
if (isContractLink) {
|
|
67
|
+
if (!contract) {
|
|
68
|
+
throw new Error("Contract options are required for contract based links");
|
|
69
|
+
}
|
|
70
|
+
__privateSet(this, _contract, new ZkBag(contract.packageId, contract));
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
static async fromUrl(url, options = {}) {
|
|
74
|
+
const parsed = new URL(url);
|
|
75
|
+
const isContractLink = parsed.hash.startsWith("#$");
|
|
76
|
+
const parsedNetwork = parsed.searchParams.get("network") === "testnet" ? "testnet" : "mainnet";
|
|
77
|
+
const network = options.network ?? parsedNetwork;
|
|
78
|
+
let link;
|
|
79
|
+
if (isContractLink) {
|
|
80
|
+
const keypair = Ed25519Keypair.fromSecretKey(fromBase64(parsed.hash.slice(2)));
|
|
81
|
+
link = new _ZkSendLink({
|
|
82
|
+
...options,
|
|
83
|
+
keypair,
|
|
84
|
+
network,
|
|
85
|
+
host: `${parsed.protocol}//${parsed.host}`,
|
|
86
|
+
path: parsed.pathname,
|
|
87
|
+
isContractLink: true
|
|
88
|
+
});
|
|
89
|
+
} else {
|
|
90
|
+
const keypair = Ed25519Keypair.fromSecretKey(
|
|
91
|
+
fromBase64(isContractLink ? parsed.hash.slice(2) : parsed.hash.slice(1))
|
|
92
|
+
);
|
|
93
|
+
link = new _ZkSendLink({
|
|
94
|
+
...options,
|
|
95
|
+
keypair,
|
|
96
|
+
network,
|
|
97
|
+
host: `${parsed.protocol}//${parsed.host}`,
|
|
98
|
+
path: parsed.pathname,
|
|
99
|
+
isContractLink: false
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
await link.loadAssets();
|
|
103
|
+
return link;
|
|
104
|
+
}
|
|
105
|
+
static async fromAddress(address, options) {
|
|
106
|
+
const link = new _ZkSendLink({
|
|
107
|
+
...options,
|
|
108
|
+
address,
|
|
109
|
+
isContractLink: true
|
|
110
|
+
});
|
|
111
|
+
await link.loadAssets();
|
|
112
|
+
return link;
|
|
113
|
+
}
|
|
114
|
+
async loadClaimedStatus() {
|
|
115
|
+
await __privateMethod(this, _ZkSendLink_instances, loadBag_fn).call(this, { loadAssets: false });
|
|
116
|
+
}
|
|
117
|
+
async loadAssets(options = {}) {
|
|
118
|
+
if (__privateGet(this, _contract)) {
|
|
119
|
+
await __privateMethod(this, _ZkSendLink_instances, loadBag_fn).call(this, options);
|
|
120
|
+
} else {
|
|
121
|
+
await __privateMethod(this, _ZkSendLink_instances, loadOwnedObjects_fn).call(this, options);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async claimAssets(address, {
|
|
125
|
+
reclaim,
|
|
126
|
+
sign
|
|
127
|
+
} = {}) {
|
|
128
|
+
if (!this.keypair && !sign) {
|
|
129
|
+
throw new Error("Cannot claim assets without links keypair");
|
|
130
|
+
}
|
|
131
|
+
if (this.claimed) {
|
|
132
|
+
throw new Error("Assets have already been claimed");
|
|
133
|
+
}
|
|
134
|
+
if (!this.assets) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
"Link assets could not be loaded. Link has not been indexed or has already been claimed"
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
if (!__privateGet(this, _contract)) {
|
|
140
|
+
const bytes2 = await this.createClaimTransaction(address).build({
|
|
141
|
+
client: __privateGet(this, _client)
|
|
142
|
+
});
|
|
143
|
+
const signature2 = sign ? await sign(bytes2) : (await this.keypair.signTransaction(bytes2)).signature;
|
|
144
|
+
return __privateGet(this, _client).executeTransactionBlock({
|
|
145
|
+
transactionBlock: bytes2,
|
|
146
|
+
signature: signature2
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
if (!this.assets) {
|
|
150
|
+
await __privateMethod(this, _ZkSendLink_instances, loadBag_fn).call(this);
|
|
151
|
+
}
|
|
152
|
+
const tx = this.createClaimTransaction(address, { reclaim });
|
|
153
|
+
const sponsored = await __privateMethod(this, _ZkSendLink_instances, createSponsoredTransaction_fn).call(this, tx, address, reclaim ? address : this.keypair.toHaneulAddress());
|
|
154
|
+
const bytes = fromBase64(sponsored.bytes);
|
|
155
|
+
const signature = sign ? await sign(bytes) : (await this.keypair.signTransaction(bytes)).signature;
|
|
156
|
+
const { digest } = await __privateMethod(this, _ZkSendLink_instances, executeSponsoredTransaction_fn).call(this, sponsored, signature);
|
|
157
|
+
const result = await __privateGet(this, _client).waitForTransaction({
|
|
158
|
+
digest,
|
|
159
|
+
options: { showEffects: true }
|
|
160
|
+
});
|
|
161
|
+
if (result.effects?.status.status !== "success") {
|
|
162
|
+
throw new Error(
|
|
163
|
+
`Claim transaction failed: ${result.effects?.status.error ?? "Unknown error"}`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
createClaimTransaction(address, {
|
|
169
|
+
reclaim
|
|
170
|
+
} = {}) {
|
|
171
|
+
if (!__privateGet(this, _contract)) {
|
|
172
|
+
return __privateMethod(this, _ZkSendLink_instances, createNonContractClaimTransaction_fn).call(this, address);
|
|
173
|
+
}
|
|
174
|
+
if (!this.keypair && !reclaim) {
|
|
175
|
+
throw new Error("Cannot claim assets without the links keypair");
|
|
176
|
+
}
|
|
177
|
+
const tx = new Transaction();
|
|
178
|
+
const sender = reclaim ? address : this.keypair.toHaneulAddress();
|
|
179
|
+
tx.setSender(sender);
|
|
180
|
+
const store = tx.object(__privateGet(this, _contract).ids.bagStoreId);
|
|
181
|
+
const command = reclaim ? __privateGet(this, _contract).reclaim({ arguments: [store, this.address] }) : __privateGet(this, _contract).init_claim({ arguments: [store] });
|
|
182
|
+
const [bag, proof] = tx.add(command);
|
|
183
|
+
const objectsToTransfer = [];
|
|
184
|
+
const objects = [...this.assets?.coins ?? [], ...this.assets?.nfts ?? []];
|
|
185
|
+
for (const object of objects) {
|
|
186
|
+
objectsToTransfer.push(
|
|
187
|
+
__privateGet(this, _contract).claim({
|
|
188
|
+
arguments: [
|
|
189
|
+
bag,
|
|
190
|
+
proof,
|
|
191
|
+
tx.receivingRef({
|
|
192
|
+
objectId: object.objectId,
|
|
193
|
+
version: object.version,
|
|
194
|
+
digest: object.digest
|
|
195
|
+
})
|
|
196
|
+
],
|
|
197
|
+
typeArguments: [object.type]
|
|
198
|
+
})
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
if (objectsToTransfer.length > 0) {
|
|
202
|
+
tx.transferObjects(objectsToTransfer, address);
|
|
203
|
+
}
|
|
204
|
+
tx.add(__privateGet(this, _contract).finalize({ arguments: [bag, proof] }));
|
|
205
|
+
return tx;
|
|
206
|
+
}
|
|
207
|
+
async createRegenerateTransaction(sender, options = {}) {
|
|
208
|
+
if (!this.assets) {
|
|
209
|
+
await __privateMethod(this, _ZkSendLink_instances, loadBag_fn).call(this);
|
|
210
|
+
}
|
|
211
|
+
if (this.claimed) {
|
|
212
|
+
throw new Error("Assets have already been claimed");
|
|
213
|
+
}
|
|
214
|
+
if (!__privateGet(this, _contract)) {
|
|
215
|
+
throw new Error("Regenerating non-contract based links is not supported");
|
|
216
|
+
}
|
|
217
|
+
const tx = new Transaction();
|
|
218
|
+
tx.setSender(sender);
|
|
219
|
+
const store = tx.object(__privateGet(this, _contract).ids.bagStoreId);
|
|
220
|
+
const newLinkKp = Ed25519Keypair.generate();
|
|
221
|
+
const newLink = new ZkSendLinkBuilder({
|
|
222
|
+
...options,
|
|
223
|
+
sender,
|
|
224
|
+
client: __privateGet(this, _client),
|
|
225
|
+
contract: __privateGet(this, _contract).ids,
|
|
226
|
+
host: __privateGet(this, _host),
|
|
227
|
+
path: __privateGet(this, _path),
|
|
228
|
+
keypair: newLinkKp
|
|
229
|
+
});
|
|
230
|
+
const to = tx.pure.address(newLinkKp.toHaneulAddress());
|
|
231
|
+
tx.add(__privateGet(this, _contract).update_receiver({ arguments: [store, this.address, to] }));
|
|
232
|
+
return {
|
|
233
|
+
url: newLink.getLink(),
|
|
234
|
+
transaction: tx
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
_client = new WeakMap();
|
|
239
|
+
_contract = new WeakMap();
|
|
240
|
+
_network = new WeakMap();
|
|
241
|
+
_host = new WeakMap();
|
|
242
|
+
_path = new WeakMap();
|
|
243
|
+
_claimApi = new WeakMap();
|
|
244
|
+
_gasCoin = new WeakMap();
|
|
245
|
+
_hasSui = new WeakMap();
|
|
246
|
+
_ownedObjects = new WeakMap();
|
|
247
|
+
_ZkSendLink_instances = new WeakSet();
|
|
248
|
+
loadBagObject_fn = async function() {
|
|
249
|
+
if (!__privateGet(this, _contract)) {
|
|
250
|
+
throw new Error("Cannot load bag object for non-contract based links");
|
|
251
|
+
}
|
|
252
|
+
const bagField = await __privateGet(this, _client).getDynamicFieldObject({
|
|
253
|
+
parentId: __privateGet(this, _contract).ids.bagStoreTableId,
|
|
254
|
+
name: {
|
|
255
|
+
type: "address",
|
|
256
|
+
value: this.address
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
this.bagObject = bagField.data;
|
|
260
|
+
if (this.bagObject) {
|
|
261
|
+
this.claimed = false;
|
|
262
|
+
}
|
|
263
|
+
};
|
|
264
|
+
loadBag_fn = async function({
|
|
265
|
+
transaction,
|
|
266
|
+
loadAssets = true,
|
|
267
|
+
loadClaimedAssets = loadAssets
|
|
268
|
+
} = {}) {
|
|
269
|
+
if (!__privateGet(this, _contract)) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (!this.bagObject || !this.claimed) {
|
|
273
|
+
await __privateMethod(this, _ZkSendLink_instances, loadBagObject_fn).call(this);
|
|
274
|
+
}
|
|
275
|
+
if (!loadAssets) {
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
if (!this.bagObject) {
|
|
279
|
+
if (loadClaimedAssets) {
|
|
280
|
+
await __privateMethod(this, _ZkSendLink_instances, loadClaimedAssets_fn).call(this);
|
|
281
|
+
}
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
const bagId = this.bagObject.content.fields.value.fields?.id?.id;
|
|
285
|
+
if (bagId && transaction?.balanceChanges && transaction.objectChanges) {
|
|
286
|
+
this.assets = getAssetsFromTransaction({
|
|
287
|
+
transaction,
|
|
288
|
+
address: bagId,
|
|
289
|
+
isSent: false
|
|
290
|
+
});
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
const itemIds = this.bagObject?.content?.fields?.value?.fields?.item_ids.fields.contents;
|
|
294
|
+
this.creatorAddress = this.bagObject?.content?.fields?.value?.fields?.owner;
|
|
295
|
+
if (!itemIds) {
|
|
296
|
+
throw new Error("Invalid bag field");
|
|
297
|
+
}
|
|
298
|
+
const objectsResponse = await __privateGet(this, _client).multiGetObjects({
|
|
299
|
+
ids: itemIds,
|
|
300
|
+
options: {
|
|
301
|
+
showType: true,
|
|
302
|
+
showContent: true
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
this.assets = {
|
|
306
|
+
balances: [],
|
|
307
|
+
nfts: [],
|
|
308
|
+
coins: []
|
|
309
|
+
};
|
|
310
|
+
const balances = /* @__PURE__ */ new Map();
|
|
311
|
+
objectsResponse.forEach((object, i) => {
|
|
312
|
+
if (!object.data || !object.data.type) {
|
|
313
|
+
throw new Error(`Failed to load claimable object ${itemIds[i]}`);
|
|
314
|
+
}
|
|
315
|
+
const type = parseStructTag(normalizeStructTag(object.data.type));
|
|
316
|
+
if (type.address === normalizeHaneulAddress("0x2") && type.module === "coin" && type.name === "Coin") {
|
|
317
|
+
this.assets.coins.push({
|
|
318
|
+
objectId: object.data.objectId,
|
|
319
|
+
type: object.data.type,
|
|
320
|
+
version: object.data.version,
|
|
321
|
+
digest: object.data.digest
|
|
322
|
+
});
|
|
323
|
+
if (object.data.content?.dataType === "moveObject") {
|
|
324
|
+
const amount = BigInt(object.data.content.fields.balance);
|
|
325
|
+
const coinType = normalizeStructTag(
|
|
326
|
+
parseStructTag(object.data.content.type).typeParams[0]
|
|
327
|
+
);
|
|
328
|
+
if (!balances.has(coinType)) {
|
|
329
|
+
balances.set(coinType, { coinType, amount });
|
|
330
|
+
} else {
|
|
331
|
+
balances.get(coinType).amount += amount;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
} else {
|
|
335
|
+
this.assets.nfts.push({
|
|
336
|
+
objectId: object.data.objectId,
|
|
337
|
+
type: object.data.type,
|
|
338
|
+
version: object.data.version,
|
|
339
|
+
digest: object.data.digest
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
this.assets.balances = [...balances.values()];
|
|
344
|
+
};
|
|
345
|
+
loadClaimedAssets_fn = async function() {
|
|
346
|
+
const result = await __privateGet(this, _client).queryTransactionBlocks({
|
|
347
|
+
limit: 1,
|
|
348
|
+
filter: {
|
|
349
|
+
FromAddress: this.address
|
|
350
|
+
},
|
|
351
|
+
options: {
|
|
352
|
+
showObjectChanges: true,
|
|
353
|
+
showBalanceChanges: true,
|
|
354
|
+
showInput: true
|
|
355
|
+
}
|
|
356
|
+
});
|
|
357
|
+
if (!result?.data[0]) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const [tx] = result.data;
|
|
361
|
+
if (tx.transaction?.data.transaction.kind !== "ProgrammableTransaction") {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
const transfer = tx.transaction.data.transaction.transactions.findLast(
|
|
365
|
+
(tx2) => "TransferObjects" in tx2
|
|
366
|
+
);
|
|
367
|
+
if (!transfer) {
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const receiverArg = transfer.TransferObjects[1];
|
|
371
|
+
if (!(typeof receiverArg === "object" && "Input" in receiverArg)) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
const input = tx.transaction.data.transaction.inputs[receiverArg.Input];
|
|
375
|
+
if (input.type !== "pure") {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const receiver = typeof input.value === "string" ? input.value : bcs.Address.parse(new Uint8Array(input.value.Pure));
|
|
379
|
+
this.claimed = true;
|
|
380
|
+
this.claimedBy = receiver;
|
|
381
|
+
this.assets = getAssetsFromTransaction({
|
|
382
|
+
transaction: tx,
|
|
383
|
+
address: receiver,
|
|
384
|
+
isSent: false
|
|
385
|
+
});
|
|
386
|
+
};
|
|
387
|
+
createSponsoredTransaction_fn = async function(tx, claimer, sender) {
|
|
388
|
+
return __privateMethod(this, _ZkSendLink_instances, fetch_fn).call(this, "transaction-blocks/sponsor", {
|
|
389
|
+
method: "POST",
|
|
390
|
+
body: JSON.stringify({
|
|
391
|
+
network: __privateGet(this, _network),
|
|
392
|
+
sender,
|
|
393
|
+
claimer,
|
|
394
|
+
transactionBlockKindBytes: toBase64(
|
|
395
|
+
await tx.build({
|
|
396
|
+
onlyTransactionKind: true,
|
|
397
|
+
client: __privateGet(this, _client)
|
|
398
|
+
})
|
|
399
|
+
)
|
|
400
|
+
})
|
|
401
|
+
});
|
|
402
|
+
};
|
|
403
|
+
executeSponsoredTransaction_fn = async function(input, signature) {
|
|
404
|
+
return __privateMethod(this, _ZkSendLink_instances, fetch_fn).call(this, `transaction-blocks/sponsor/${input.digest}`, {
|
|
405
|
+
method: "POST",
|
|
406
|
+
body: JSON.stringify({
|
|
407
|
+
signature
|
|
408
|
+
})
|
|
409
|
+
});
|
|
410
|
+
};
|
|
411
|
+
fetch_fn = async function(path, init) {
|
|
412
|
+
const res = await fetch(`${__privateGet(this, _claimApi)}/v1/${path}`, {
|
|
413
|
+
...init,
|
|
414
|
+
headers: {
|
|
415
|
+
...init.headers,
|
|
416
|
+
"Content-Type": "application/json"
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
if (!res.ok) {
|
|
420
|
+
console.error(`${__privateGet(this, _claimApi)}/v1/${path}`, await res.text());
|
|
421
|
+
throw new Error(`Request to claim API failed with status code ${res.status}`);
|
|
422
|
+
}
|
|
423
|
+
const { data } = await res.json();
|
|
424
|
+
return data;
|
|
425
|
+
};
|
|
426
|
+
listNonContractClaimableAssets_fn = async function() {
|
|
427
|
+
const balances = [];
|
|
428
|
+
const nfts = [];
|
|
429
|
+
const coins = [];
|
|
430
|
+
if (__privateGet(this, _ownedObjects).length === 0 && !__privateGet(this, _hasSui)) {
|
|
431
|
+
return {
|
|
432
|
+
balances,
|
|
433
|
+
nfts,
|
|
434
|
+
coins
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
const address = new Ed25519Keypair().toHaneulAddress();
|
|
438
|
+
const normalizedAddress = normalizeHaneulAddress(address);
|
|
439
|
+
const tx = this.createClaimTransaction(normalizedAddress);
|
|
440
|
+
if (__privateGet(this, _gasCoin) || !__privateGet(this, _hasSui)) {
|
|
441
|
+
tx.setGasPayment([]);
|
|
442
|
+
}
|
|
443
|
+
const dryRun = await __privateGet(this, _client).dryRunTransactionBlock({
|
|
444
|
+
transactionBlock: await tx.build({ client: __privateGet(this, _client) })
|
|
445
|
+
});
|
|
446
|
+
dryRun.balanceChanges.forEach((balanceChange) => {
|
|
447
|
+
if (BigInt(balanceChange.amount) > 0n && isOwner(balanceChange.owner, normalizedAddress)) {
|
|
448
|
+
balances.push({
|
|
449
|
+
coinType: normalizeStructTag(balanceChange.coinType),
|
|
450
|
+
amount: BigInt(balanceChange.amount)
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
dryRun.objectChanges.forEach((objectChange) => {
|
|
455
|
+
if ("objectType" in objectChange) {
|
|
456
|
+
const type = parseStructTag(objectChange.objectType);
|
|
457
|
+
if (type.address === normalizeHaneulAddress("0x2") && type.module === "coin" && type.name === "Coin") {
|
|
458
|
+
if (ownedAfterChange(objectChange, normalizedAddress)) {
|
|
459
|
+
coins.push(objectChange);
|
|
460
|
+
}
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
if (ownedAfterChange(objectChange, normalizedAddress)) {
|
|
465
|
+
nfts.push(objectChange);
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
return {
|
|
469
|
+
balances,
|
|
470
|
+
nfts,
|
|
471
|
+
coins
|
|
472
|
+
};
|
|
473
|
+
};
|
|
474
|
+
createNonContractClaimTransaction_fn = function(address) {
|
|
475
|
+
if (!this.keypair) {
|
|
476
|
+
throw new Error("Cannot claim assets without the links keypair");
|
|
477
|
+
}
|
|
478
|
+
const tx = new Transaction();
|
|
479
|
+
tx.setSender(this.keypair.toHaneulAddress());
|
|
480
|
+
const objectsToTransfer = __privateGet(this, _ownedObjects).filter((object) => {
|
|
481
|
+
if (__privateGet(this, _gasCoin)) {
|
|
482
|
+
if (object.objectId === __privateGet(this, _gasCoin).coinObjectId) {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
} else if (object.type === HANEUL_COIN_OBJECT_TYPE) {
|
|
486
|
+
return false;
|
|
487
|
+
}
|
|
488
|
+
return true;
|
|
489
|
+
}).map((object) => tx.object(object.objectId));
|
|
490
|
+
if (__privateGet(this, _gasCoin) && this.creatorAddress) {
|
|
491
|
+
tx.transferObjects([tx.gas], this.creatorAddress);
|
|
492
|
+
} else {
|
|
493
|
+
objectsToTransfer.push(tx.gas);
|
|
494
|
+
}
|
|
495
|
+
if (objectsToTransfer.length > 0) {
|
|
496
|
+
tx.transferObjects(objectsToTransfer, address);
|
|
497
|
+
}
|
|
498
|
+
return tx;
|
|
499
|
+
};
|
|
500
|
+
loadOwnedObjects_fn = async function({
|
|
501
|
+
loadClaimedAssets = true
|
|
502
|
+
} = {}) {
|
|
503
|
+
this.assets = {
|
|
504
|
+
nfts: [],
|
|
505
|
+
balances: [],
|
|
506
|
+
coins: []
|
|
507
|
+
};
|
|
508
|
+
let nextCursor;
|
|
509
|
+
do {
|
|
510
|
+
const ownedObjects = await __privateGet(this, _client).getOwnedObjects({
|
|
511
|
+
cursor: nextCursor,
|
|
512
|
+
owner: this.address,
|
|
513
|
+
options: {
|
|
514
|
+
showType: true,
|
|
515
|
+
showContent: true
|
|
516
|
+
}
|
|
517
|
+
});
|
|
518
|
+
nextCursor = ownedObjects.hasNextPage ? ownedObjects.nextCursor : null;
|
|
519
|
+
for (const object of ownedObjects.data) {
|
|
520
|
+
if (object.data) {
|
|
521
|
+
__privateGet(this, _ownedObjects).push({
|
|
522
|
+
objectId: normalizeHaneulObjectId(object.data.objectId),
|
|
523
|
+
version: object.data.version,
|
|
524
|
+
digest: object.data.digest,
|
|
525
|
+
type: normalizeStructTag(object.data.type)
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
} while (nextCursor);
|
|
530
|
+
const coins = await __privateGet(this, _client).getCoins({
|
|
531
|
+
coinType: HANEUL_COIN_TYPE,
|
|
532
|
+
owner: this.address
|
|
533
|
+
});
|
|
534
|
+
__privateSet(this, _hasSui, coins.data.length > 0);
|
|
535
|
+
__privateSet(this, _gasCoin, coins.data.find((coin) => BigInt(coin.balance) % 1000n === 987n));
|
|
536
|
+
const result = await __privateGet(this, _client).queryTransactionBlocks({
|
|
537
|
+
limit: 1,
|
|
538
|
+
order: "ascending",
|
|
539
|
+
filter: {
|
|
540
|
+
ToAddress: this.address
|
|
541
|
+
},
|
|
542
|
+
options: {
|
|
543
|
+
showInput: true,
|
|
544
|
+
showBalanceChanges: true,
|
|
545
|
+
showObjectChanges: true
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
this.creatorAddress = result.data[0]?.transaction?.data.sender;
|
|
549
|
+
if (__privateGet(this, _hasSui) || __privateGet(this, _ownedObjects).length > 0) {
|
|
550
|
+
this.claimed = false;
|
|
551
|
+
this.assets = await __privateMethod(this, _ZkSendLink_instances, listNonContractClaimableAssets_fn).call(this);
|
|
552
|
+
} else if (result.data[0] && loadClaimedAssets) {
|
|
553
|
+
this.claimed = true;
|
|
554
|
+
await __privateMethod(this, _ZkSendLink_instances, loadClaimedAssets_fn).call(this);
|
|
555
|
+
}
|
|
556
|
+
};
|
|
557
|
+
let ZkSendLink = _ZkSendLink;
|
|
558
|
+
export {
|
|
559
|
+
ZkSendLink
|
|
560
|
+
};
|
|
561
|
+
//# sourceMappingURL=claim.js.map
|