@bananapus/nana-sdk-core 1.2.0 → 1.3.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/dist/cjs/utils/hook.d.ts +15 -0
- package/dist/cjs/utils/hook.d.ts.map +1 -1
- package/dist/cjs/utils/hook.js +20 -0
- package/dist/cjs/utils/hook.js.map +1 -1
- package/dist/cjs/v6/cashOut.d.ts +23 -0
- package/dist/cjs/v6/cashOut.d.ts.map +1 -1
- package/dist/cjs/v6/cashOut.js +35 -0
- package/dist/cjs/v6/cashOut.js.map +1 -1
- package/dist/cjs/v6/cashOut.test.js +20 -0
- package/dist/cjs/v6/cashOut.test.js.map +1 -1
- package/dist/cjs/v6/index.d.ts +1 -0
- package/dist/cjs/v6/index.d.ts.map +1 -1
- package/dist/cjs/v6/index.js +1 -0
- package/dist/cjs/v6/index.js.map +1 -1
- package/dist/cjs/v6/nft.d.ts +98 -0
- package/dist/cjs/v6/nft.d.ts.map +1 -0
- package/dist/cjs/v6/nft.js +166 -0
- package/dist/cjs/v6/nft.js.map +1 -0
- package/dist/cjs/v6/nft.test.d.ts +2 -0
- package/dist/cjs/v6/nft.test.d.ts.map +1 -0
- package/dist/cjs/v6/nft.test.js +206 -0
- package/dist/cjs/v6/nft.test.js.map +1 -0
- package/dist/cjs/v6/pay.d.ts +13 -5
- package/dist/cjs/v6/pay.d.ts.map +1 -1
- package/dist/cjs/v6/pay.js +15 -18
- package/dist/cjs/v6/pay.js.map +1 -1
- package/dist/cjs/v6/pay.test.js +7 -0
- package/dist/cjs/v6/pay.test.js.map +1 -1
- package/dist/esm/utils/hook.d.ts +15 -0
- package/dist/esm/utils/hook.d.ts.map +1 -1
- package/dist/esm/utils/hook.js +20 -1
- package/dist/esm/utils/hook.js.map +1 -1
- package/dist/esm/v6/cashOut.d.ts +23 -0
- package/dist/esm/v6/cashOut.d.ts.map +1 -1
- package/dist/esm/v6/cashOut.js +34 -0
- package/dist/esm/v6/cashOut.js.map +1 -1
- package/dist/esm/v6/cashOut.test.js +22 -2
- package/dist/esm/v6/cashOut.test.js.map +1 -1
- package/dist/esm/v6/index.d.ts +1 -0
- package/dist/esm/v6/index.d.ts.map +1 -1
- package/dist/esm/v6/index.js +1 -0
- package/dist/esm/v6/index.js.map +1 -1
- package/dist/esm/v6/nft.d.ts +98 -0
- package/dist/esm/v6/nft.d.ts.map +1 -0
- package/dist/esm/v6/nft.js +160 -0
- package/dist/esm/v6/nft.js.map +1 -0
- package/dist/esm/v6/nft.test.d.ts +2 -0
- package/dist/esm/v6/nft.test.d.ts.map +1 -0
- package/dist/esm/v6/nft.test.js +204 -0
- package/dist/esm/v6/nft.test.js.map +1 -0
- package/dist/esm/v6/pay.d.ts +13 -5
- package/dist/esm/v6/pay.d.ts.map +1 -1
- package/dist/esm/v6/pay.js +17 -20
- package/dist/esm/v6/pay.js.map +1 -1
- package/dist/esm/v6/pay.test.js +7 -0
- package/dist/esm/v6/pay.test.js.map +1 -1
- package/dist/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Address, Hex, PublicClient } from "viem";
|
|
2
|
+
import { JBChainId } from "../types.js";
|
|
3
|
+
/**
|
|
4
|
+
* JB721TiersHookStore's `DISCOUNT_DENOMINATOR`: a tier's `discountPercent` is
|
|
5
|
+
* out of 200, so the shopper-facing "% off" is `discountPercent / 2`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const DISCOUNT_DENOMINATOR = 200n;
|
|
8
|
+
/**
|
|
9
|
+
* A tier's effective (discounted) price, matching the on-chain formula in
|
|
10
|
+
* JB721TiersHookStore: `price - mulDiv(price, discountPercent, 200)` with
|
|
11
|
+
* integer-floor division.
|
|
12
|
+
*
|
|
13
|
+
* @param price The tier's full (undiscounted) price.
|
|
14
|
+
* @param discountPercent The tier's discount, out of 200 (`DISCOUNT_DENOMINATOR`).
|
|
15
|
+
*/
|
|
16
|
+
export declare function effectiveTierPrice(price: bigint, discountPercent: number | bigint): bigint;
|
|
17
|
+
/**
|
|
18
|
+
* A single 721 tier a project sells.
|
|
19
|
+
*/
|
|
20
|
+
export interface Project721Tier {
|
|
21
|
+
id: number;
|
|
22
|
+
/** Full (undiscounted) price in the shop's pricing terms. */
|
|
23
|
+
price: bigint;
|
|
24
|
+
remainingSupply: number;
|
|
25
|
+
initialSupply: number;
|
|
26
|
+
votingUnits: bigint;
|
|
27
|
+
reserveFrequency: number;
|
|
28
|
+
category: number;
|
|
29
|
+
/** Out of 200 — see {@link DISCOUNT_DENOMINATOR}. */
|
|
30
|
+
discountPercent: number;
|
|
31
|
+
encodedIpfsUri: Hex;
|
|
32
|
+
/** tokenUriResolver output (data URI), or "" if the hook has no resolver. */
|
|
33
|
+
resolvedUri: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* A project's resolved 721 tiers hook ("shop"): the hook, its store, the
|
|
37
|
+
* metadata id target for pay/cash-out metadata, the pricing context, and tiers.
|
|
38
|
+
*/
|
|
39
|
+
export interface Project721Shop {
|
|
40
|
+
/** The project's 721 tiers hook (the ruleset data hook / revnet hook). */
|
|
41
|
+
hook: Address;
|
|
42
|
+
/** The hook's tiers store. */
|
|
43
|
+
store: Address;
|
|
44
|
+
/**
|
|
45
|
+
* The hook's `METADATA_ID_TARGET` (shared implementation address). Pass this
|
|
46
|
+
* to {@link build721PayMetadata} / {@link build721CashOutMetadata}, never the
|
|
47
|
+
* `hook` address.
|
|
48
|
+
*/
|
|
49
|
+
metadataIdTarget: Address;
|
|
50
|
+
/** The hook's pricing context: `currency` id and `decimals`. */
|
|
51
|
+
pricing: {
|
|
52
|
+
currency: number;
|
|
53
|
+
decimals: number;
|
|
54
|
+
};
|
|
55
|
+
tiers: Project721Tier[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Read a JB721 hook's `METADATA_ID_TARGET` — the shared *implementation* address
|
|
59
|
+
* that pay/cash-out metadata ids must key off (a delegatecall clone reports the
|
|
60
|
+
* implementation, not itself). Falls back to `hook` if the read reverts (e.g. an
|
|
61
|
+
* older hook without the getter), which is only correct for a non-clone hook.
|
|
62
|
+
*
|
|
63
|
+
* @param client A viem public client on the given chain.
|
|
64
|
+
* @param args.hook The project's 721 tiers hook (clone) address.
|
|
65
|
+
*/
|
|
66
|
+
export declare function get721MetadataIdTarget(client: PublicClient, { hook }: {
|
|
67
|
+
chainId: JBChainId;
|
|
68
|
+
hook: Address;
|
|
69
|
+
}): Promise<Address>;
|
|
70
|
+
/**
|
|
71
|
+
* Resolve a project's 721 tiers hook, its store, metadata id target, pricing
|
|
72
|
+
* context, and tiers in one call.
|
|
73
|
+
*
|
|
74
|
+
* Hook resolution mirrors the app patterns: revnets read
|
|
75
|
+
* `REVOwner.tiered721HookOf`; custom projects read the current ruleset's pay
|
|
76
|
+
* data hook — either the omnichain deployer (the real hook lives in
|
|
77
|
+
* `JBOmnichainDeployer.tiered721HookOf(projectId, rulesetId)`) or the 721 hook
|
|
78
|
+
* itself, verified by probing `STORE()` (a revert means it is not a 721 hook, so
|
|
79
|
+
* the project has no shop).
|
|
80
|
+
*
|
|
81
|
+
* Returns `null` when the project authoritatively has no 721 shop. RPC failures
|
|
82
|
+
* on authoritative reads throw, so a transient error surfaces as an error rather
|
|
83
|
+
* than a false "no shop".
|
|
84
|
+
*
|
|
85
|
+
* @param client A viem public client on the given chain.
|
|
86
|
+
* @param args.projectId The project (or revnet) id.
|
|
87
|
+
* @param args.isRevnet Whether the project is a revnet (changes hook resolution).
|
|
88
|
+
* @param args.tierLimit Max tiers to read from `tiersOf`. Defaults to 100.
|
|
89
|
+
* @param args.categories Tier categories to filter by (empty = all). Defaults to `[]`.
|
|
90
|
+
*/
|
|
91
|
+
export declare function getProject721Shop(client: PublicClient, { chainId, projectId, isRevnet, tierLimit, categories, }: {
|
|
92
|
+
chainId: JBChainId;
|
|
93
|
+
projectId: bigint;
|
|
94
|
+
isRevnet: boolean;
|
|
95
|
+
tierLimit?: number;
|
|
96
|
+
categories?: bigint[];
|
|
97
|
+
}): Promise<Project721Shop | null>;
|
|
98
|
+
//# sourceMappingURL=nft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nft.d.ts","sourceRoot":"","sources":["../../../src/v6/nft.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAe,MAAM,MAAM,CAAC;AAQ/D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAEzC;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GAAG,MAAM,GAC/B,MAAM,CAKR;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,GAAG,CAAC;IACpB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,OAAO,CAAC;IACd,8BAA8B;IAC9B,KAAK,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gEAAgE;IAChE,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAChD,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,YAAY,EACpB,EAAE,IAAI,EAAE,EAAE;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC9C,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,YAAY,EACpB,EACE,OAAO,EACP,SAAS,EACT,QAAQ,EACR,SAAe,EACf,UAAe,GAChB,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,GACA,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAkGhC"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { zeroAddress } from "viem";
|
|
2
|
+
import { JBOmnichainDeployerContracts } from "../contracts.js";
|
|
3
|
+
import { jb721TiersHookAbi, jb721TiersHookStoreAbi, jbContractAddress, jbOmnichainDeployerAbi, } from "../generated/juicebox.js";
|
|
4
|
+
import { getRevnetTiered721Hook } from "./revnets.js";
|
|
5
|
+
import { getCurrentRuleset } from "./rulesets.js";
|
|
6
|
+
/**
|
|
7
|
+
* JB721TiersHookStore's `DISCOUNT_DENOMINATOR`: a tier's `discountPercent` is
|
|
8
|
+
* out of 200, so the shopper-facing "% off" is `discountPercent / 2`.
|
|
9
|
+
*/
|
|
10
|
+
export const DISCOUNT_DENOMINATOR = 200n;
|
|
11
|
+
/**
|
|
12
|
+
* A tier's effective (discounted) price, matching the on-chain formula in
|
|
13
|
+
* JB721TiersHookStore: `price - mulDiv(price, discountPercent, 200)` with
|
|
14
|
+
* integer-floor division.
|
|
15
|
+
*
|
|
16
|
+
* @param price The tier's full (undiscounted) price.
|
|
17
|
+
* @param discountPercent The tier's discount, out of 200 (`DISCOUNT_DENOMINATOR`).
|
|
18
|
+
*/
|
|
19
|
+
export function effectiveTierPrice(price, discountPercent) {
|
|
20
|
+
let discount = BigInt(discountPercent);
|
|
21
|
+
if (discount <= 0n)
|
|
22
|
+
return price;
|
|
23
|
+
if (discount > DISCOUNT_DENOMINATOR)
|
|
24
|
+
discount = DISCOUNT_DENOMINATOR;
|
|
25
|
+
return price - (price * discount) / DISCOUNT_DENOMINATOR;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read a JB721 hook's `METADATA_ID_TARGET` — the shared *implementation* address
|
|
29
|
+
* that pay/cash-out metadata ids must key off (a delegatecall clone reports the
|
|
30
|
+
* implementation, not itself). Falls back to `hook` if the read reverts (e.g. an
|
|
31
|
+
* older hook without the getter), which is only correct for a non-clone hook.
|
|
32
|
+
*
|
|
33
|
+
* @param client A viem public client on the given chain.
|
|
34
|
+
* @param args.hook The project's 721 tiers hook (clone) address.
|
|
35
|
+
*/
|
|
36
|
+
export async function get721MetadataIdTarget(client, { hook }) {
|
|
37
|
+
return client
|
|
38
|
+
.readContract({
|
|
39
|
+
address: hook,
|
|
40
|
+
abi: jb721TiersHookAbi,
|
|
41
|
+
functionName: "METADATA_ID_TARGET",
|
|
42
|
+
})
|
|
43
|
+
.catch(() => hook);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Resolve a project's 721 tiers hook, its store, metadata id target, pricing
|
|
47
|
+
* context, and tiers in one call.
|
|
48
|
+
*
|
|
49
|
+
* Hook resolution mirrors the app patterns: revnets read
|
|
50
|
+
* `REVOwner.tiered721HookOf`; custom projects read the current ruleset's pay
|
|
51
|
+
* data hook — either the omnichain deployer (the real hook lives in
|
|
52
|
+
* `JBOmnichainDeployer.tiered721HookOf(projectId, rulesetId)`) or the 721 hook
|
|
53
|
+
* itself, verified by probing `STORE()` (a revert means it is not a 721 hook, so
|
|
54
|
+
* the project has no shop).
|
|
55
|
+
*
|
|
56
|
+
* Returns `null` when the project authoritatively has no 721 shop. RPC failures
|
|
57
|
+
* on authoritative reads throw, so a transient error surfaces as an error rather
|
|
58
|
+
* than a false "no shop".
|
|
59
|
+
*
|
|
60
|
+
* @param client A viem public client on the given chain.
|
|
61
|
+
* @param args.projectId The project (or revnet) id.
|
|
62
|
+
* @param args.isRevnet Whether the project is a revnet (changes hook resolution).
|
|
63
|
+
* @param args.tierLimit Max tiers to read from `tiersOf`. Defaults to 100.
|
|
64
|
+
* @param args.categories Tier categories to filter by (empty = all). Defaults to `[]`.
|
|
65
|
+
*/
|
|
66
|
+
export async function getProject721Shop(client, { chainId, projectId, isRevnet, tierLimit = 100, categories = [], }) {
|
|
67
|
+
// 1. Resolve the 721 hook.
|
|
68
|
+
let hook = null;
|
|
69
|
+
// A non-authoritative candidate is the ruleset data hook, which might be some
|
|
70
|
+
// other kind of hook; the STORE() probe below decides.
|
|
71
|
+
let authoritative = true;
|
|
72
|
+
if (isRevnet) {
|
|
73
|
+
const revnetHook = await getRevnetTiered721Hook(client, {
|
|
74
|
+
chainId,
|
|
75
|
+
revnetId: projectId,
|
|
76
|
+
});
|
|
77
|
+
hook = revnetHook !== zeroAddress ? revnetHook : null;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const { ruleset, metadata } = await getCurrentRuleset(client, {
|
|
81
|
+
chainId,
|
|
82
|
+
projectId,
|
|
83
|
+
});
|
|
84
|
+
const dataHook = metadata.dataHook;
|
|
85
|
+
if (metadata.useDataHookForPay && dataHook && dataHook !== zeroAddress) {
|
|
86
|
+
const omni = jbContractAddress["6"][JBOmnichainDeployerContracts.JBOmnichainDeployer]?.[chainId];
|
|
87
|
+
if (omni && dataHook.toLowerCase() === omni.toLowerCase()) {
|
|
88
|
+
// Omnichain project: the real 721 hook lives in the deployer's
|
|
89
|
+
// per-ruleset mapping.
|
|
90
|
+
const [omniHook] = await client.readContract({
|
|
91
|
+
address: omni,
|
|
92
|
+
abi: jbOmnichainDeployerAbi,
|
|
93
|
+
functionName: "tiered721HookOf",
|
|
94
|
+
args: [projectId, BigInt(ruleset.id)],
|
|
95
|
+
});
|
|
96
|
+
hook = omniHook !== zeroAddress ? omniHook : null;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
// Single-chain custom project: the data hook may be the 721 hook itself.
|
|
100
|
+
hook = dataHook;
|
|
101
|
+
authoritative = false;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!hook)
|
|
106
|
+
return null;
|
|
107
|
+
// 2. The hook's store. For a non-authoritative candidate a revert means "not a
|
|
108
|
+
// 721 hook" (no shop); for an authoritative one, let failures throw.
|
|
109
|
+
const readStore = () => client.readContract({
|
|
110
|
+
address: hook,
|
|
111
|
+
abi: jb721TiersHookAbi,
|
|
112
|
+
functionName: "STORE",
|
|
113
|
+
});
|
|
114
|
+
const store = authoritative
|
|
115
|
+
? await readStore()
|
|
116
|
+
: await readStore().catch(() => null);
|
|
117
|
+
if (!store)
|
|
118
|
+
return null;
|
|
119
|
+
// 3. Metadata id target + pricing context. Pricing is meaningless without the
|
|
120
|
+
// hook's exact currency + decimals, so a failure here is an error, not a
|
|
121
|
+
// fallback.
|
|
122
|
+
const [metadataIdTarget, pricingRaw] = await Promise.all([
|
|
123
|
+
get721MetadataIdTarget(client, { chainId, hook }),
|
|
124
|
+
client.readContract({
|
|
125
|
+
address: hook,
|
|
126
|
+
abi: jb721TiersHookAbi,
|
|
127
|
+
functionName: "pricingContext",
|
|
128
|
+
}),
|
|
129
|
+
]);
|
|
130
|
+
// 4. The tiers, with resolver URIs included so callers can name tiers without
|
|
131
|
+
// a per-tier resolver read.
|
|
132
|
+
const raw = await client.readContract({
|
|
133
|
+
address: store,
|
|
134
|
+
abi: jb721TiersHookStoreAbi,
|
|
135
|
+
functionName: "tiersOf",
|
|
136
|
+
args: [hook, categories, true, 0n, BigInt(tierLimit)],
|
|
137
|
+
});
|
|
138
|
+
const tiers = raw
|
|
139
|
+
.filter((tier) => tier.initialSupply > 0)
|
|
140
|
+
.map((tier) => ({
|
|
141
|
+
id: tier.id,
|
|
142
|
+
price: tier.price,
|
|
143
|
+
remainingSupply: tier.remainingSupply,
|
|
144
|
+
initialSupply: tier.initialSupply,
|
|
145
|
+
votingUnits: tier.votingUnits,
|
|
146
|
+
reserveFrequency: tier.reserveFrequency,
|
|
147
|
+
category: tier.category,
|
|
148
|
+
discountPercent: tier.discountPercent,
|
|
149
|
+
encodedIpfsUri: tier.encodedIpfsUri,
|
|
150
|
+
resolvedUri: tier.resolvedUri ?? "",
|
|
151
|
+
}));
|
|
152
|
+
return {
|
|
153
|
+
hook,
|
|
154
|
+
store,
|
|
155
|
+
metadataIdTarget,
|
|
156
|
+
pricing: { currency: Number(pricingRaw[0]), decimals: Number(pricingRaw[1]) },
|
|
157
|
+
tiers,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=nft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nft.js","sourceRoot":"","sources":["../../../src/v6/nft.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nft.test.d.ts","sourceRoot":"","sources":["../../../src/v6/nft.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { zeroAddress } from "viem";
|
|
2
|
+
import { describe, expect, test } from "vitest";
|
|
3
|
+
import { JBOmnichainDeployerContracts } from "../contracts.js";
|
|
4
|
+
import { jbContractAddress } from "../generated/juicebox.js";
|
|
5
|
+
import { DISCOUNT_DENOMINATOR, effectiveTierPrice, get721MetadataIdTarget, getProject721Shop, } from "./nft.js";
|
|
6
|
+
const chainId = 11155111;
|
|
7
|
+
const hook = "0x1111111111111111111111111111111111111111";
|
|
8
|
+
const impl = "0x2222222222222222222222222222222222222222";
|
|
9
|
+
const store = "0x3333333333333333333333333333333333333333";
|
|
10
|
+
describe("effectiveTierPrice", () => {
|
|
11
|
+
test("floors like on-chain mulDiv(price, discountPercent, 200)", () => {
|
|
12
|
+
// 100 - floor(100 * 25 / 200) = 100 - 12 = 88.
|
|
13
|
+
expect(effectiveTierPrice(100n, 25)).toEqual(88n);
|
|
14
|
+
});
|
|
15
|
+
test("no discount returns the full price", () => {
|
|
16
|
+
expect(effectiveTierPrice(1000n, 0)).toEqual(1000n);
|
|
17
|
+
});
|
|
18
|
+
test("full discount (denominator) is free", () => {
|
|
19
|
+
expect(effectiveTierPrice(1000n, Number(DISCOUNT_DENOMINATOR))).toEqual(0n);
|
|
20
|
+
});
|
|
21
|
+
test("clamps discounts above the denominator to free", () => {
|
|
22
|
+
expect(effectiveTierPrice(1000n, 500)).toEqual(0n);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("get721MetadataIdTarget", () => {
|
|
26
|
+
test("returns METADATA_ID_TARGET (the implementation, not the clone)", async () => {
|
|
27
|
+
const client = {
|
|
28
|
+
readContract: async () => impl,
|
|
29
|
+
};
|
|
30
|
+
expect(await get721MetadataIdTarget(client, { chainId, hook })).toEqual(impl);
|
|
31
|
+
});
|
|
32
|
+
test("falls back to the hook address if the getter reverts", async () => {
|
|
33
|
+
const client = {
|
|
34
|
+
readContract: async () => {
|
|
35
|
+
throw new Error("no such function");
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
expect(await get721MetadataIdTarget(client, { chainId, hook })).toEqual(hook);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
describe("getProject721Shop", () => {
|
|
42
|
+
test("returns null when a revnet has no 721 hook", async () => {
|
|
43
|
+
const client = {
|
|
44
|
+
// getRevnetTiered721Hook -> zero address.
|
|
45
|
+
readContract: async () => zeroAddress,
|
|
46
|
+
};
|
|
47
|
+
expect(await getProject721Shop(client, {
|
|
48
|
+
chainId,
|
|
49
|
+
projectId: 1n,
|
|
50
|
+
isRevnet: true,
|
|
51
|
+
})).toBeNull();
|
|
52
|
+
});
|
|
53
|
+
test("resolves a revnet shop: hook, store, target, pricing, tiers", async () => {
|
|
54
|
+
const client = {
|
|
55
|
+
readContract: async ({ address, functionName, }) => {
|
|
56
|
+
if (functionName === "tiered721HookOf")
|
|
57
|
+
return hook; // REVOwner
|
|
58
|
+
if (address === hook && functionName === "STORE")
|
|
59
|
+
return store;
|
|
60
|
+
if (functionName === "METADATA_ID_TARGET")
|
|
61
|
+
return impl;
|
|
62
|
+
if (functionName === "pricingContext")
|
|
63
|
+
return [61166n, 18n];
|
|
64
|
+
if (functionName === "tiersOf") {
|
|
65
|
+
return [
|
|
66
|
+
{
|
|
67
|
+
id: 1,
|
|
68
|
+
price: 1000n,
|
|
69
|
+
remainingSupply: 5,
|
|
70
|
+
initialSupply: 10,
|
|
71
|
+
votingUnits: 0n,
|
|
72
|
+
reserveFrequency: 0,
|
|
73
|
+
reserveBeneficiary: zeroAddress,
|
|
74
|
+
encodedIpfsUri: `0x${"11".repeat(32)}`,
|
|
75
|
+
category: 0,
|
|
76
|
+
discountPercent: 0,
|
|
77
|
+
flags: {},
|
|
78
|
+
splitPercent: 0,
|
|
79
|
+
resolvedUri: "",
|
|
80
|
+
},
|
|
81
|
+
// Filtered out: initialSupply 0.
|
|
82
|
+
{
|
|
83
|
+
id: 2,
|
|
84
|
+
price: 0n,
|
|
85
|
+
remainingSupply: 0,
|
|
86
|
+
initialSupply: 0,
|
|
87
|
+
votingUnits: 0n,
|
|
88
|
+
reserveFrequency: 0,
|
|
89
|
+
reserveBeneficiary: zeroAddress,
|
|
90
|
+
encodedIpfsUri: `0x${"00".repeat(32)}`,
|
|
91
|
+
category: 0,
|
|
92
|
+
discountPercent: 0,
|
|
93
|
+
flags: {},
|
|
94
|
+
splitPercent: 0,
|
|
95
|
+
resolvedUri: "",
|
|
96
|
+
},
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
throw new Error(`unexpected read ${functionName}`);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
const shop = await getProject721Shop(client, {
|
|
103
|
+
chainId,
|
|
104
|
+
projectId: 1n,
|
|
105
|
+
isRevnet: true,
|
|
106
|
+
});
|
|
107
|
+
expect(shop).not.toBeNull();
|
|
108
|
+
expect(shop.hook).toEqual(hook);
|
|
109
|
+
expect(shop.store).toEqual(store);
|
|
110
|
+
expect(shop.metadataIdTarget).toEqual(impl);
|
|
111
|
+
expect(shop.pricing).toEqual({ currency: 61166, decimals: 18 });
|
|
112
|
+
expect(shop.tiers).toHaveLength(1);
|
|
113
|
+
expect(shop.tiers[0]).toMatchObject({ id: 1, price: 1000n });
|
|
114
|
+
});
|
|
115
|
+
const tiersOfOne = () => [
|
|
116
|
+
{
|
|
117
|
+
id: 1,
|
|
118
|
+
price: 1000n,
|
|
119
|
+
remainingSupply: 5,
|
|
120
|
+
initialSupply: 10,
|
|
121
|
+
votingUnits: 0n,
|
|
122
|
+
reserveFrequency: 0,
|
|
123
|
+
reserveBeneficiary: zeroAddress,
|
|
124
|
+
encodedIpfsUri: `0x${"11".repeat(32)}`,
|
|
125
|
+
category: 0,
|
|
126
|
+
discountPercent: 0,
|
|
127
|
+
flags: {},
|
|
128
|
+
splitPercent: 0,
|
|
129
|
+
resolvedUri: "",
|
|
130
|
+
},
|
|
131
|
+
];
|
|
132
|
+
// The custom-project omnichain deployer address on chain 11155111, read from
|
|
133
|
+
// the SDK's own address book so the branch matches real wiring.
|
|
134
|
+
const omniDeployer = jbContractAddress["6"][JBOmnichainDeployerContracts.JBOmnichainDeployer]["11155111"];
|
|
135
|
+
test("custom project: resolves the real hook via the omnichain deployer", async () => {
|
|
136
|
+
const client = {
|
|
137
|
+
readContract: async ({ address, functionName, }) => {
|
|
138
|
+
// currentRulesetOf -> [ruleset, metadata] with the deployer as data hook.
|
|
139
|
+
if (functionName === "currentRulesetOf") {
|
|
140
|
+
return [
|
|
141
|
+
{ id: 7 },
|
|
142
|
+
{ useDataHookForPay: true, dataHook: omniDeployer },
|
|
143
|
+
];
|
|
144
|
+
}
|
|
145
|
+
// The deployer maps to the real clone hook.
|
|
146
|
+
if (address.toLowerCase() === omniDeployer.toLowerCase() &&
|
|
147
|
+
functionName === "tiered721HookOf") {
|
|
148
|
+
return [hook, false];
|
|
149
|
+
}
|
|
150
|
+
if (address === hook && functionName === "STORE")
|
|
151
|
+
return store;
|
|
152
|
+
if (functionName === "METADATA_ID_TARGET")
|
|
153
|
+
return impl;
|
|
154
|
+
if (functionName === "pricingContext")
|
|
155
|
+
return [1n, 18n];
|
|
156
|
+
if (functionName === "tiersOf")
|
|
157
|
+
return tiersOfOne();
|
|
158
|
+
throw new Error(`unexpected read ${functionName} @ ${address}`);
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
const shop = await getProject721Shop(client, {
|
|
162
|
+
chainId: 11155111,
|
|
163
|
+
projectId: 9n,
|
|
164
|
+
isRevnet: false,
|
|
165
|
+
});
|
|
166
|
+
expect(shop.hook).toEqual(hook);
|
|
167
|
+
expect(shop.metadataIdTarget).toEqual(impl);
|
|
168
|
+
});
|
|
169
|
+
test("custom project: data hook that is not a 721 hook is no shop", async () => {
|
|
170
|
+
const notAHook = "0x4444444444444444444444444444444444444444";
|
|
171
|
+
const client = {
|
|
172
|
+
readContract: async ({ functionName }) => {
|
|
173
|
+
if (functionName === "currentRulesetOf") {
|
|
174
|
+
return [{ id: 7 }, { useDataHookForPay: true, dataHook: notAHook }];
|
|
175
|
+
}
|
|
176
|
+
// Non-authoritative candidate: STORE() reverts => not a 721 hook.
|
|
177
|
+
if (functionName === "STORE")
|
|
178
|
+
throw new Error("no STORE");
|
|
179
|
+
throw new Error(`unexpected read ${functionName}`);
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
expect(await getProject721Shop(client, {
|
|
183
|
+
chainId: 11155111,
|
|
184
|
+
projectId: 9n,
|
|
185
|
+
isRevnet: false,
|
|
186
|
+
})).toBeNull();
|
|
187
|
+
});
|
|
188
|
+
test("custom project: no pay data hook is no shop", async () => {
|
|
189
|
+
const client = {
|
|
190
|
+
readContract: async ({ functionName }) => {
|
|
191
|
+
if (functionName === "currentRulesetOf") {
|
|
192
|
+
return [{ id: 7 }, { useDataHookForPay: false, dataHook: zeroAddress }];
|
|
193
|
+
}
|
|
194
|
+
throw new Error(`unexpected read ${functionName}`);
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
expect(await getProject721Shop(client, {
|
|
198
|
+
chainId: 11155111,
|
|
199
|
+
projectId: 9n,
|
|
200
|
+
isRevnet: false,
|
|
201
|
+
})).toBeNull();
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
//# sourceMappingURL=nft.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nft.test.js","sourceRoot":"","sources":["../../../src/v6/nft.test.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/v6/pay.d.ts
CHANGED
|
@@ -92,18 +92,26 @@ export declare function previewPay(client: PublicClient, { terminal, projectId,
|
|
|
92
92
|
* Build pay metadata instructing a project's JB721 tiers hook to mint specific tiers.
|
|
93
93
|
*
|
|
94
94
|
* The tier payload is `abi.encode(bool allowOverspending, uint16[] tierIdsToMint)`,
|
|
95
|
-
* keyed by the hook's metadata id (`bytes4(bytes20(
|
|
95
|
+
* keyed by the hook's metadata id (`bytes4(bytes20(metadataIdTarget) ^
|
|
96
96
|
* bytes20(keccak256("pay")))`) and packed into the JBMetadataResolver
|
|
97
97
|
* word-offset-table format.
|
|
98
98
|
*
|
|
99
|
-
* @param args.
|
|
99
|
+
* @param args.metadataIdTarget The hook's `METADATA_ID_TARGET` — the shared
|
|
100
|
+
* *implementation* address, NOT the project's clone hook address (see
|
|
101
|
+
* {@link get721MetadataIdTarget}). Passing the clone address makes the hook ignore
|
|
102
|
+
* the tiers and the payment mints ZERO NFTs (it succeeds, minting only tokens).
|
|
103
|
+
* @param args.hookAddress Deprecated alias for `metadataIdTarget`. Only correct
|
|
104
|
+
* when it already holds `METADATA_ID_TARGET`; prefer `metadataIdTarget`.
|
|
100
105
|
* @param args.tierIdsToMint The tier ids to mint, one entry per NFT.
|
|
101
106
|
* @param args.allowOverspending Whether payment beyond the tiers' total price is
|
|
102
|
-
* allowed (excess mints no NFT). Defaults to true.
|
|
107
|
+
* allowed (excess mints no NFT). Defaults to true. Note the hook still gates this
|
|
108
|
+
* on its store's `preventOverspending` flag.
|
|
103
109
|
* @returns The metadata to pass as `pay`'s `metadata` argument.
|
|
104
110
|
*/
|
|
105
|
-
export declare function build721PayMetadata({ hookAddress, tierIdsToMint, allowOverspending, }: {
|
|
106
|
-
|
|
111
|
+
export declare function build721PayMetadata({ metadataIdTarget, hookAddress, tierIdsToMint, allowOverspending, }: {
|
|
112
|
+
metadataIdTarget?: Address;
|
|
113
|
+
/** @deprecated Use `metadataIdTarget`. */
|
|
114
|
+
hookAddress?: Address;
|
|
107
115
|
tierIdsToMint: bigint[];
|
|
108
116
|
allowOverspending?: boolean;
|
|
109
117
|
}): Hex;
|
package/dist/esm/v6/pay.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pay.d.ts","sourceRoot":"","sources":["../../../src/v6/pay.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,GAAG,EACH,YAAY,
|
|
1
|
+
{"version":3,"file":"pay.d.ts","sourceRoot":"","sources":["../../../src/v6/pay.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EACP,GAAG,EACH,YAAY,EAEb,MAAM,MAAM,CAAC;AAEd,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,SAAS,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,kBAAkB,CAAC;IAC/B,YAAY,EAAE,KAAK,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACvE,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,EACN,WAAW,EACX,iBAAsB,EACtB,IAAS,EACT,QAAe,GAChB,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,GAAG,cAAc,CAmBjB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,qBAAqB,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,YAAY,EACpB,EACE,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,EACN,WAAW,EACX,QAAe,GAChB,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,GACA,OAAO,CAAC,UAAU,CAAC,CAUrB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,iBAA8C,GAC/C,EAAE;IACD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B,GAAG,GAAG,CAeN"}
|
package/dist/esm/v6/pay.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { encodeAbiParameters, } from "viem";
|
|
2
2
|
import { DEFAULT_ALLOW_OVERSPENDING, NATIVE_TOKEN } from "../constants.js";
|
|
3
3
|
import { jbMultiTerminalAbi } from "../generated/juicebox.js";
|
|
4
|
-
import { createHookMetadata } from "../utils/hook.js";
|
|
4
|
+
import { createHookMetadata, hookMetadataId } from "../utils/hook.js";
|
|
5
5
|
/**
|
|
6
6
|
* Build a `pay(projectId, token, amount, beneficiary, minReturnedTokens, memo,
|
|
7
7
|
* metadata)` transaction request for a v6 terminal.
|
|
@@ -72,35 +72,32 @@ export async function previewPay(client, { terminal, projectId, token, amount, b
|
|
|
72
72
|
});
|
|
73
73
|
return { beneficiaryTokenCount, reservedTokenCount };
|
|
74
74
|
}
|
|
75
|
-
/**
|
|
76
|
-
* The metadata id a JB721 hook looks up in pay metadata:
|
|
77
|
-
* `bytes4(bytes20(target) ^ bytes20(keccak256("pay")))`, where the target is the hook's
|
|
78
|
-
* own address (`JB721Hook.METADATA_ID_TARGET` is `address(this)`).
|
|
79
|
-
*
|
|
80
|
-
* @link https://github.com/Bananapus/nana-core-v6/blob/main/src/libraries/JBMetadataResolver.sol (`getId`)
|
|
81
|
-
*/
|
|
82
|
-
function pay721MetadataId(hookAddress) {
|
|
83
|
-
const targetBytes = toBytes(hookAddress).slice(0, 20);
|
|
84
|
-
const purposeBytes = toBytes(keccak256(toBytes("pay"))).slice(0, 20);
|
|
85
|
-
const xorResult = targetBytes.map((byte, i) => byte ^ purposeBytes[i]);
|
|
86
|
-
return bytesToHex(xorResult.slice(0, 4));
|
|
87
|
-
}
|
|
88
75
|
/**
|
|
89
76
|
* Build pay metadata instructing a project's JB721 tiers hook to mint specific tiers.
|
|
90
77
|
*
|
|
91
78
|
* The tier payload is `abi.encode(bool allowOverspending, uint16[] tierIdsToMint)`,
|
|
92
|
-
* keyed by the hook's metadata id (`bytes4(bytes20(
|
|
79
|
+
* keyed by the hook's metadata id (`bytes4(bytes20(metadataIdTarget) ^
|
|
93
80
|
* bytes20(keccak256("pay")))`) and packed into the JBMetadataResolver
|
|
94
81
|
* word-offset-table format.
|
|
95
82
|
*
|
|
96
|
-
* @param args.
|
|
83
|
+
* @param args.metadataIdTarget The hook's `METADATA_ID_TARGET` — the shared
|
|
84
|
+
* *implementation* address, NOT the project's clone hook address (see
|
|
85
|
+
* {@link get721MetadataIdTarget}). Passing the clone address makes the hook ignore
|
|
86
|
+
* the tiers and the payment mints ZERO NFTs (it succeeds, minting only tokens).
|
|
87
|
+
* @param args.hookAddress Deprecated alias for `metadataIdTarget`. Only correct
|
|
88
|
+
* when it already holds `METADATA_ID_TARGET`; prefer `metadataIdTarget`.
|
|
97
89
|
* @param args.tierIdsToMint The tier ids to mint, one entry per NFT.
|
|
98
90
|
* @param args.allowOverspending Whether payment beyond the tiers' total price is
|
|
99
|
-
* allowed (excess mints no NFT). Defaults to true.
|
|
91
|
+
* allowed (excess mints no NFT). Defaults to true. Note the hook still gates this
|
|
92
|
+
* on its store's `preventOverspending` flag.
|
|
100
93
|
* @returns The metadata to pass as `pay`'s `metadata` argument.
|
|
101
94
|
*/
|
|
102
|
-
export function build721PayMetadata({ hookAddress, tierIdsToMint, allowOverspending = DEFAULT_ALLOW_OVERSPENDING, }) {
|
|
95
|
+
export function build721PayMetadata({ metadataIdTarget, hookAddress, tierIdsToMint, allowOverspending = DEFAULT_ALLOW_OVERSPENDING, }) {
|
|
96
|
+
const target = metadataIdTarget ?? hookAddress;
|
|
97
|
+
if (!target) {
|
|
98
|
+
throw new Error("build721PayMetadata requires metadataIdTarget");
|
|
99
|
+
}
|
|
103
100
|
const tierPayload = encodeAbiParameters([{ type: "bool" }, { type: "uint16[]" }], [allowOverspending, tierIdsToMint.map(Number)]);
|
|
104
|
-
return createHookMetadata([
|
|
101
|
+
return createHookMetadata([hookMetadataId(target, "pay")], [tierPayload]);
|
|
105
102
|
}
|
|
106
103
|
//# sourceMappingURL=pay.js.map
|
package/dist/esm/v6/pay.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pay.js","sourceRoot":"","sources":["../../../src/v6/pay.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,
|
|
1
|
+
{"version":3,"file":"pay.js","sourceRoot":"","sources":["../../../src/v6/pay.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,mBAAmB,GACpB,MAAM,MAAM,CAAC;AACd,OAAO,EAAE,0BAA0B,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAetE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,UAAU,CAAC,EACzB,OAAO,EACP,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,EACN,WAAW,EACX,iBAAiB,GAAG,EAAE,EACtB,IAAI,GAAG,EAAE,EACT,QAAQ,GAAG,IAAI,GAWhB;IACC,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,WAAW,EAAE,CAAC;IAEpE,OAAO;QACL,OAAO;QACP,OAAO,EAAE,QAAQ;QACjB,GAAG,EAAE,kBAAkB;QACvB,YAAY,EAAE,KAAK;QACnB,IAAI,EAAE;YACJ,SAAS;YACT,KAAK;YACL,MAAM;YACN,WAAW;YACX,iBAAiB;YACjB,IAAI;YACJ,QAAQ;SACT;QACD,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;KAC9B,CAAC;AACJ,CAAC;AAgBD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAoB,EACpB,EACE,QAAQ,EACR,SAAS,EACT,KAAK,EACL,MAAM,EACN,WAAW,EACX,QAAQ,GAAG,IAAI,GAShB;IAED,MAAM,CAAC,EAAE,qBAAqB,EAAE,kBAAkB,CAAC,GACjD,MAAM,MAAM,CAAC,YAAY,CAAC;QACxB,OAAO,EAAE,QAAQ;QACjB,GAAG,EAAE,kBAAkB;QACvB,YAAY,EAAE,eAAe;QAC7B,IAAI,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,QAAQ,CAAC;KACxD,CAAC,CAAC;IAEL,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC;AACvD,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAClC,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,iBAAiB,GAAG,0BAA0B,GAO/C;IACC,MAAM,MAAM,GAAG,gBAAgB,IAAI,WAAW,CAAC;IAC/C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,WAAW,GAAG,mBAAmB,CACrC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EACxC,CAAC,iBAAiB,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAC/C,CAAC;IAEF,OAAO,kBAAkB,CACvB,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,EAC/B,CAAC,WAAW,CAAC,CACP,CAAC;AACX,CAAC"}
|
package/dist/esm/v6/pay.test.js
CHANGED
|
@@ -124,5 +124,12 @@ describe("pay", () => {
|
|
|
124
124
|
// 0xadc75680 (first 4 bytes of keccak256("pay")) XOR 0x11111111.
|
|
125
125
|
expect(sliceHex(metadata, 32, 36)).toEqual("0xbcd64791");
|
|
126
126
|
});
|
|
127
|
+
test("build721PayMetadata metadataIdTarget matches the hookAddress alias", () => {
|
|
128
|
+
const target = "0x1111111111111111111111111111111111111111";
|
|
129
|
+
expect(build721PayMetadata({ metadataIdTarget: target, tierIdsToMint: [1n] })).toEqual(build721PayMetadata({ hookAddress: target, tierIdsToMint: [1n] }));
|
|
130
|
+
});
|
|
131
|
+
test("build721PayMetadata throws when no target is given", () => {
|
|
132
|
+
expect(() => build721PayMetadata({ tierIdsToMint: [1n] })).toThrow(/metadataIdTarget/);
|
|
133
|
+
});
|
|
127
134
|
});
|
|
128
135
|
//# sourceMappingURL=pay.test.js.map
|