@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
package/dist/cjs/utils/hook.d.ts
CHANGED
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
import { Address, Hex } from "viem";
|
|
2
|
+
/**
|
|
3
|
+
* The metadata lookup id a JB hook resolves via `JBMetadataResolver.getId`:
|
|
4
|
+
* `bytes4(bytes20(target) ^ bytes20(keccak256(purpose)))`.
|
|
5
|
+
*
|
|
6
|
+
* For JB721 hooks, `target` MUST be the hook's `METADATA_ID_TARGET` — which is
|
|
7
|
+
* `address(this)` in the *implementation's* constructor, so every delegatecall
|
|
8
|
+
* clone reports the shared implementation address, NOT its own clone address.
|
|
9
|
+
* Passing the clone address yields an id the hook never matches, so the pay or
|
|
10
|
+
* cash out silently ignores the tier/token payload. Resolve the target with
|
|
11
|
+
* `get721MetadataIdTarget` rather than passing a hook address directly.
|
|
12
|
+
*
|
|
13
|
+
* @link https://github.com/Bananapus/nana-core-v6/blob/main/src/libraries/JBMetadataResolver.sol (`getId`)
|
|
14
|
+
*/
|
|
15
|
+
export declare function hookMetadataId(target: Address, purpose: string): Hex;
|
|
1
16
|
/**
|
|
2
17
|
*
|
|
3
18
|
* Create metadata for pay or redeem hooks.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/utils/hook.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hook.d.ts","sourceRoot":"","sources":["../../../src/utils/hook.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAEP,GAAG,EAMJ,MAAM,MAAM,CAAC;AAEd;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,GAAG,CAKpE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,iBA8CpE"}
|
package/dist/cjs/utils/hook.js
CHANGED
|
@@ -1,7 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hookMetadataId = hookMetadataId;
|
|
3
4
|
exports.createHookMetadata = createHookMetadata;
|
|
4
5
|
const viem_1 = require("viem");
|
|
6
|
+
/**
|
|
7
|
+
* The metadata lookup id a JB hook resolves via `JBMetadataResolver.getId`:
|
|
8
|
+
* `bytes4(bytes20(target) ^ bytes20(keccak256(purpose)))`.
|
|
9
|
+
*
|
|
10
|
+
* For JB721 hooks, `target` MUST be the hook's `METADATA_ID_TARGET` — which is
|
|
11
|
+
* `address(this)` in the *implementation's* constructor, so every delegatecall
|
|
12
|
+
* clone reports the shared implementation address, NOT its own clone address.
|
|
13
|
+
* Passing the clone address yields an id the hook never matches, so the pay or
|
|
14
|
+
* cash out silently ignores the tier/token payload. Resolve the target with
|
|
15
|
+
* `get721MetadataIdTarget` rather than passing a hook address directly.
|
|
16
|
+
*
|
|
17
|
+
* @link https://github.com/Bananapus/nana-core-v6/blob/main/src/libraries/JBMetadataResolver.sol (`getId`)
|
|
18
|
+
*/
|
|
19
|
+
function hookMetadataId(target, purpose) {
|
|
20
|
+
const targetBytes = (0, viem_1.toBytes)(target).slice(0, 20);
|
|
21
|
+
const purposeBytes = (0, viem_1.toBytes)((0, viem_1.keccak256)((0, viem_1.toBytes)(purpose))).slice(0, 20);
|
|
22
|
+
const xored = targetBytes.map((byte, i) => byte ^ purposeBytes[i]);
|
|
23
|
+
return (0, viem_1.bytesToHex)(xored.slice(0, 4));
|
|
24
|
+
}
|
|
5
25
|
/**
|
|
6
26
|
*
|
|
7
27
|
* Create metadata for pay or redeem hooks.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../../src/utils/hook.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../../../src/utils/hook.ts"],"names":[],"mappings":";;AAwBA,wCAKC;AASD,gDA8CC;AApFD,+BASc;AAEd;;;;;;;;;;;;GAYG;AACH,SAAgB,cAAc,CAAC,MAAe,EAAE,OAAe;IAC7D,MAAM,WAAW,GAAG,IAAA,cAAO,EAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,IAAA,cAAO,EAAC,IAAA,gBAAS,EAAC,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACvE,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,OAAO,IAAA,iBAAU,EAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,kBAAkB,CAAC,GAAa,EAAE,SAAmB;IACnE,gBAAgB;IAChB,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;IAExE,oEAAoE;IACpE,IAAI,QAAQ,GAAG,IAAA,mBAAY,EAAC,CAAC,SAAS,CAAC,EAAE,CAAC,eAAQ,CAAC,CAAC,CAAC;IAErD,oEAAoE;IACpE,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,sFAAsF;IACtF,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAEjC,kHAAkH;IAClH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,8BAA8B;QAC9B,QAAQ,IAAI,IAAA,mBAAY,EAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAEhE,QAAQ,IAAI,IAAA,mBAAY,EAAC,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvD,kFAAkF;QAClF,MAAM,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC;QAEnC,wBAAwB;QACxB,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IAC5D,CAAC;IAED,qCAAqC;IACrC,IAAI,YAAY,GACd,QAAQ,CAAC,MAAM,GAAG,EAAE,KAAK,CAAC;QACxB,CAAC,CAAC,QAAQ,CAAC,MAAM;QACjB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAE/C,yBAAyB;IACzB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,YAAY,GAAG,CAAC,EAAE,GAAG,CAAS,CAAC;IAE1D,0DAA0D;IAC1D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,2BAA2B;QAC3B,QAAQ,IAAI,IAAA,mBAAY,EACtB,CAAC,OAAO,CAAC,EACT,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,CAAS,CAAC,CACjD,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACb,CAAC;IAED,2BAA2B;IAC3B,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
package/dist/cjs/v6/cashOut.d.ts
CHANGED
|
@@ -40,6 +40,29 @@ export declare function buildCashOutTx({ chainId, terminal, holder, projectId, c
|
|
|
40
40
|
beneficiary: Address;
|
|
41
41
|
metadata?: Hex;
|
|
42
42
|
}): V6CashOutTxRequest;
|
|
43
|
+
/**
|
|
44
|
+
* Build cash-out metadata instructing a project's JB721 tiers hook to burn
|
|
45
|
+
* specific NFTs and reclaim their share of surplus.
|
|
46
|
+
*
|
|
47
|
+
* The payload is `abi.encode(uint256[] tokenIds)`, keyed by the hook's cash-out
|
|
48
|
+
* metadata id (`bytes4(bytes20(metadataIdTarget) ^ bytes20(keccak256("cashOut")))`)
|
|
49
|
+
* and packed into the JBMetadataResolver word-offset-table format. This is the
|
|
50
|
+
* cash-out mirror of {@link build721PayMetadata}. The NFTs are burned by the hook
|
|
51
|
+
* itself, so no ERC-721 approval is needed; pass `cashOutCount: 0` to
|
|
52
|
+
* `cashOutTokensOf` (fungible tokens cannot co-redeem in the same call).
|
|
53
|
+
*
|
|
54
|
+
* @param args.metadataIdTarget The hook's `METADATA_ID_TARGET` — the shared
|
|
55
|
+
* *implementation* address, NOT the project's clone hook address (see
|
|
56
|
+
* {@link get721MetadataIdTarget}). Passing the clone address makes the hook ignore
|
|
57
|
+
* the token ids and no NFTs are burned.
|
|
58
|
+
* @param args.tokenIds The token ids of the NFTs to redeem. Must be non-empty,
|
|
59
|
+
* unique, and non-zero (a real NFT token id is never 0).
|
|
60
|
+
* @returns The metadata to pass as `cashOutTokensOf`'s `metadata` argument.
|
|
61
|
+
*/
|
|
62
|
+
export declare function build721CashOutMetadata({ metadataIdTarget, tokenIds, }: {
|
|
63
|
+
metadataIdTarget: Address;
|
|
64
|
+
tokenIds: bigint[];
|
|
65
|
+
}): Hex;
|
|
43
66
|
/**
|
|
44
67
|
* A cash out quote.
|
|
45
68
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cashOut.d.ts","sourceRoot":"","sources":["../../../src/v6/cashOut.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"cashOut.d.ts","sourceRoot":"","sources":["../../../src/v6/cashOut.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAuB,MAAM,MAAM,CAAC;AACvE,OAAO,EACL,kBAAkB,EAEnB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAMxC;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,SAAS,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,OAAO,kBAAkB,CAAC;IAC/B,YAAY,EAAE,iBAAiB,CAAC;IAChC,IAAI,EAAE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;CACzE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,YAAY,EACZ,cAAc,EACd,kBAAuB,EACvB,WAAW,EACX,QAAe,GAChB,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB,GAAG,kBAAkB,CAgBrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,gBAAgB,EAChB,QAAQ,GACT,EAAE;IACD,gBAAgB,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,GAAG,GAAG,CAiBN;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;OAEG;IACH,aAAa,EAAE,MAAM,CAAC;IACtB;;;;;OAKG;IACH,qBAAqB,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,EACpB,EACE,OAAO,EACP,SAAS,EACT,YAAY,EACZ,QAAc,EACd,QAA2C,GAC5C,EAAE;IACD,OAAO,EAAE,SAAS,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GACA,OAAO,CAAC,YAAY,CAAC,CAYvB"}
|
package/dist/cjs/v6/cashOut.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildCashOutTx = buildCashOutTx;
|
|
4
|
+
exports.build721CashOutMetadata = build721CashOutMetadata;
|
|
4
5
|
exports.getCashOutQuote = getCashOutQuote;
|
|
6
|
+
const viem_1 = require("viem");
|
|
5
7
|
const juicebox_js_1 = require("../generated/juicebox.js");
|
|
6
8
|
const fee_js_1 = require("../utils/fee.js");
|
|
9
|
+
const hook_js_1 = require("../utils/hook.js");
|
|
7
10
|
const currency_js_1 = require("./currency.js");
|
|
8
11
|
const types_js_1 = require("./types.js");
|
|
9
12
|
/**
|
|
@@ -40,6 +43,38 @@ function buildCashOutTx({ chainId, terminal, holder, projectId, cashOutCount, to
|
|
|
40
43
|
],
|
|
41
44
|
};
|
|
42
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Build cash-out metadata instructing a project's JB721 tiers hook to burn
|
|
48
|
+
* specific NFTs and reclaim their share of surplus.
|
|
49
|
+
*
|
|
50
|
+
* The payload is `abi.encode(uint256[] tokenIds)`, keyed by the hook's cash-out
|
|
51
|
+
* metadata id (`bytes4(bytes20(metadataIdTarget) ^ bytes20(keccak256("cashOut")))`)
|
|
52
|
+
* and packed into the JBMetadataResolver word-offset-table format. This is the
|
|
53
|
+
* cash-out mirror of {@link build721PayMetadata}. The NFTs are burned by the hook
|
|
54
|
+
* itself, so no ERC-721 approval is needed; pass `cashOutCount: 0` to
|
|
55
|
+
* `cashOutTokensOf` (fungible tokens cannot co-redeem in the same call).
|
|
56
|
+
*
|
|
57
|
+
* @param args.metadataIdTarget The hook's `METADATA_ID_TARGET` — the shared
|
|
58
|
+
* *implementation* address, NOT the project's clone hook address (see
|
|
59
|
+
* {@link get721MetadataIdTarget}). Passing the clone address makes the hook ignore
|
|
60
|
+
* the token ids and no NFTs are burned.
|
|
61
|
+
* @param args.tokenIds The token ids of the NFTs to redeem. Must be non-empty,
|
|
62
|
+
* unique, and non-zero (a real NFT token id is never 0).
|
|
63
|
+
* @returns The metadata to pass as `cashOutTokensOf`'s `metadata` argument.
|
|
64
|
+
*/
|
|
65
|
+
function build721CashOutMetadata({ metadataIdTarget, tokenIds, }) {
|
|
66
|
+
if (tokenIds.length === 0) {
|
|
67
|
+
throw new Error("build721CashOutMetadata requires at least one token id");
|
|
68
|
+
}
|
|
69
|
+
if (new Set(tokenIds.map(String)).size !== tokenIds.length) {
|
|
70
|
+
throw new Error("build721CashOutMetadata token ids must be unique");
|
|
71
|
+
}
|
|
72
|
+
if (tokenIds.some((tokenId) => tokenId <= 0n)) {
|
|
73
|
+
throw new Error("build721CashOutMetadata token ids must be positive");
|
|
74
|
+
}
|
|
75
|
+
const payload = (0, viem_1.encodeAbiParameters)([{ type: "uint256[]" }], [tokenIds]);
|
|
76
|
+
return (0, hook_js_1.createHookMetadata)([(0, hook_js_1.hookMetadataId)(metadataIdTarget, "cashOut")], [payload]);
|
|
77
|
+
}
|
|
43
78
|
/**
|
|
44
79
|
* Quote the surplus reclaimed by cashing out `cashOutCount` project tokens, via
|
|
45
80
|
* `JBTerminalStore.currentReclaimableSurplusOf(projectId, cashOutCount, [], [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cashOut.js","sourceRoot":"","sources":["../../../src/v6/cashOut.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"cashOut.js","sourceRoot":"","sources":["../../../src/v6/cashOut.ts"],"names":[],"mappings":";;AAwCA,wCAoCC;AAqBD,0DAuBC;AAyCD,0CA2BC;AA5LD,+BAAuE;AACvE,0DAGkC;AAElC,4CAAuD;AACvD,8CAAsE;AACtE,+CAAyD;AACzD,yCAAuC;AAcvC;;;;;;;;;;;;;;;;GAgBG;AACH,SAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,YAAY,EACZ,cAAc,EACd,kBAAkB,GAAG,EAAE,EACvB,WAAW,EACX,QAAQ,GAAG,IAAI,GAWhB;IACC,OAAO;QACL,OAAO;QACP,OAAO,EAAE,QAAQ;QACjB,GAAG,EAAE,gCAAkB;QACvB,YAAY,EAAE,iBAAiB;QAC/B,IAAI,EAAE;YACJ,MAAM;YACN,SAAS;YACT,YAAY;YACZ,cAAc;YACd,kBAAkB;YAClB,WAAW;YACX,QAAQ;SACT;KACF,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,SAAgB,uBAAuB,CAAC,EACtC,gBAAgB,EAChB,QAAQ,GAIT;IACC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,0BAAmB,EAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEzE,OAAO,IAAA,4BAAkB,EACvB,CAAC,IAAA,wBAAc,EAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,EAC7C,CAAC,OAAO,CAAC,CACH,CAAC;AACX,CAAC;AAmBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACI,KAAK,UAAU,eAAe,CACnC,MAAoB,EACpB,EACE,OAAO,EACP,SAAS,EACT,YAAY,EACZ,QAAQ,GAAG,GAAG,EACd,QAAQ,GAAG,MAAM,CAAC,sCAAwB,CAAC,GAO5C;IAED,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC;QAC9C,OAAO,EAAE,IAAA,oBAAS,EAAC,iBAAiB,EAAE,OAAO,CAAC;QAC9C,GAAG,EAAE,gCAAkB;QACvB,YAAY,EAAE,6BAA6B;QAC3C,IAAI,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC;KAC5D,CAAC,CAAC;IAEH,OAAO;QACL,aAAa;QACb,qBAAqB,EAAE,IAAA,6BAAoB,EAAC,aAAa,CAAC;KAC3D,CAAC;AACJ,CAAC"}
|
|
@@ -98,5 +98,25 @@ const projectId = 3n;
|
|
|
98
98
|
0x3606eb48n,
|
|
99
99
|
]);
|
|
100
100
|
});
|
|
101
|
+
(0, vitest_1.test)("build721CashOutMetadata packs the cashOut id and token ids", () => {
|
|
102
|
+
// With a target whose first 4 bytes are zero, the id is the first 4 bytes
|
|
103
|
+
// of keccak256("cashOut").
|
|
104
|
+
const metadata = (0, cashOut_js_1.build721CashOutMetadata)({
|
|
105
|
+
metadataIdTarget: "0x00000000000000000000000000000000DeaDBeef",
|
|
106
|
+
tokenIds: [1000000001n, 1000000002n],
|
|
107
|
+
});
|
|
108
|
+
(0, vitest_1.expect)((0, viem_1.sliceHex)(metadata, 0, 32)).toEqual(`0x${"00".repeat(32)}`);
|
|
109
|
+
// keccak256("cashOut") first 4 bytes, then the payload word offset (2).
|
|
110
|
+
(0, vitest_1.expect)((0, viem_1.sliceHex)(metadata, 32, 36)).toEqual("0x86b14ff4");
|
|
111
|
+
(0, vitest_1.expect)((0, viem_1.sliceHex)(metadata, 36, 37)).toEqual("0x02");
|
|
112
|
+
const [tokenIds] = (0, viem_1.decodeAbiParameters)([{ type: "uint256[]" }], (0, viem_1.sliceHex)(metadata, 64));
|
|
113
|
+
(0, vitest_1.expect)(tokenIds).toEqual([1000000001n, 1000000002n]);
|
|
114
|
+
});
|
|
115
|
+
(0, vitest_1.test)("build721CashOutMetadata rejects empty, duplicate, and zero token ids", () => {
|
|
116
|
+
const target = "0x00000000000000000000000000000000DeaDBeef";
|
|
117
|
+
(0, vitest_1.expect)(() => (0, cashOut_js_1.build721CashOutMetadata)({ metadataIdTarget: target, tokenIds: [] })).toThrow(/at least one/);
|
|
118
|
+
(0, vitest_1.expect)(() => (0, cashOut_js_1.build721CashOutMetadata)({ metadataIdTarget: target, tokenIds: [1n, 1n] })).toThrow(/unique/);
|
|
119
|
+
(0, vitest_1.expect)(() => (0, cashOut_js_1.build721CashOutMetadata)({ metadataIdTarget: target, tokenIds: [0n] })).toThrow(/positive/);
|
|
120
|
+
});
|
|
101
121
|
});
|
|
102
122
|
//# sourceMappingURL=cashOut.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cashOut.test.js","sourceRoot":"","sources":["../../../src/v6/cashOut.test.ts"],"names":[],"mappings":";;AAAA,+
|
|
1
|
+
{"version":3,"file":"cashOut.test.js","sourceRoot":"","sources":["../../../src/v6/cashOut.test.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/v6/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/v6/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/v6/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
|
package/dist/cjs/v6/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __exportStar(require("./revnets.js"), exports);
|
|
|
25
25
|
__exportStar(require("./terminals.js"), exports);
|
|
26
26
|
__exportStar(require("./pay.js"), exports);
|
|
27
27
|
__exportStar(require("./cashOut.js"), exports);
|
|
28
|
+
__exportStar(require("./nft.js"), exports);
|
|
28
29
|
__exportStar(require("./tokens.js"), exports);
|
|
29
30
|
__exportStar(require("./permissions.js"), exports);
|
|
30
31
|
__exportStar(require("./suckers.js"), exports);
|
package/dist/cjs/v6/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/v6/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,gDAA8B;AAC9B,4CAA0B;AAC1B,8CAA4B;AAC5B,iDAA+B;AAC/B,gDAA8B;AAC9B,8CAA4B;AAC5B,+CAA6B;AAC7B,iDAA+B;AAC/B,2CAAyB;AACzB,+CAA6B;AAC7B,8CAA4B;AAC5B,mDAAiC;AACjC,+CAA6B;AAC7B,6CAA2B"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/v6/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,gDAA8B;AAC9B,4CAA0B;AAC1B,8CAA4B;AAC5B,iDAA+B;AAC/B,gDAA8B;AAC9B,8CAA4B;AAC5B,+CAA6B;AAC7B,iDAA+B;AAC/B,2CAAyB;AACzB,+CAA6B;AAC7B,2CAAyB;AACzB,8CAA4B;AAC5B,mDAAiC;AACjC,+CAA6B;AAC7B,6CAA2B"}
|
|
@@ -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,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DISCOUNT_DENOMINATOR = void 0;
|
|
4
|
+
exports.effectiveTierPrice = effectiveTierPrice;
|
|
5
|
+
exports.get721MetadataIdTarget = get721MetadataIdTarget;
|
|
6
|
+
exports.getProject721Shop = getProject721Shop;
|
|
7
|
+
const viem_1 = require("viem");
|
|
8
|
+
const contracts_js_1 = require("../contracts.js");
|
|
9
|
+
const juicebox_js_1 = require("../generated/juicebox.js");
|
|
10
|
+
const revnets_js_1 = require("./revnets.js");
|
|
11
|
+
const rulesets_js_1 = require("./rulesets.js");
|
|
12
|
+
/**
|
|
13
|
+
* JB721TiersHookStore's `DISCOUNT_DENOMINATOR`: a tier's `discountPercent` is
|
|
14
|
+
* out of 200, so the shopper-facing "% off" is `discountPercent / 2`.
|
|
15
|
+
*/
|
|
16
|
+
exports.DISCOUNT_DENOMINATOR = 200n;
|
|
17
|
+
/**
|
|
18
|
+
* A tier's effective (discounted) price, matching the on-chain formula in
|
|
19
|
+
* JB721TiersHookStore: `price - mulDiv(price, discountPercent, 200)` with
|
|
20
|
+
* integer-floor division.
|
|
21
|
+
*
|
|
22
|
+
* @param price The tier's full (undiscounted) price.
|
|
23
|
+
* @param discountPercent The tier's discount, out of 200 (`DISCOUNT_DENOMINATOR`).
|
|
24
|
+
*/
|
|
25
|
+
function effectiveTierPrice(price, discountPercent) {
|
|
26
|
+
let discount = BigInt(discountPercent);
|
|
27
|
+
if (discount <= 0n)
|
|
28
|
+
return price;
|
|
29
|
+
if (discount > exports.DISCOUNT_DENOMINATOR)
|
|
30
|
+
discount = exports.DISCOUNT_DENOMINATOR;
|
|
31
|
+
return price - (price * discount) / exports.DISCOUNT_DENOMINATOR;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Read a JB721 hook's `METADATA_ID_TARGET` — the shared *implementation* address
|
|
35
|
+
* that pay/cash-out metadata ids must key off (a delegatecall clone reports the
|
|
36
|
+
* implementation, not itself). Falls back to `hook` if the read reverts (e.g. an
|
|
37
|
+
* older hook without the getter), which is only correct for a non-clone hook.
|
|
38
|
+
*
|
|
39
|
+
* @param client A viem public client on the given chain.
|
|
40
|
+
* @param args.hook The project's 721 tiers hook (clone) address.
|
|
41
|
+
*/
|
|
42
|
+
async function get721MetadataIdTarget(client, { hook }) {
|
|
43
|
+
return client
|
|
44
|
+
.readContract({
|
|
45
|
+
address: hook,
|
|
46
|
+
abi: juicebox_js_1.jb721TiersHookAbi,
|
|
47
|
+
functionName: "METADATA_ID_TARGET",
|
|
48
|
+
})
|
|
49
|
+
.catch(() => hook);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Resolve a project's 721 tiers hook, its store, metadata id target, pricing
|
|
53
|
+
* context, and tiers in one call.
|
|
54
|
+
*
|
|
55
|
+
* Hook resolution mirrors the app patterns: revnets read
|
|
56
|
+
* `REVOwner.tiered721HookOf`; custom projects read the current ruleset's pay
|
|
57
|
+
* data hook — either the omnichain deployer (the real hook lives in
|
|
58
|
+
* `JBOmnichainDeployer.tiered721HookOf(projectId, rulesetId)`) or the 721 hook
|
|
59
|
+
* itself, verified by probing `STORE()` (a revert means it is not a 721 hook, so
|
|
60
|
+
* the project has no shop).
|
|
61
|
+
*
|
|
62
|
+
* Returns `null` when the project authoritatively has no 721 shop. RPC failures
|
|
63
|
+
* on authoritative reads throw, so a transient error surfaces as an error rather
|
|
64
|
+
* than a false "no shop".
|
|
65
|
+
*
|
|
66
|
+
* @param client A viem public client on the given chain.
|
|
67
|
+
* @param args.projectId The project (or revnet) id.
|
|
68
|
+
* @param args.isRevnet Whether the project is a revnet (changes hook resolution).
|
|
69
|
+
* @param args.tierLimit Max tiers to read from `tiersOf`. Defaults to 100.
|
|
70
|
+
* @param args.categories Tier categories to filter by (empty = all). Defaults to `[]`.
|
|
71
|
+
*/
|
|
72
|
+
async function getProject721Shop(client, { chainId, projectId, isRevnet, tierLimit = 100, categories = [], }) {
|
|
73
|
+
// 1. Resolve the 721 hook.
|
|
74
|
+
let hook = null;
|
|
75
|
+
// A non-authoritative candidate is the ruleset data hook, which might be some
|
|
76
|
+
// other kind of hook; the STORE() probe below decides.
|
|
77
|
+
let authoritative = true;
|
|
78
|
+
if (isRevnet) {
|
|
79
|
+
const revnetHook = await (0, revnets_js_1.getRevnetTiered721Hook)(client, {
|
|
80
|
+
chainId,
|
|
81
|
+
revnetId: projectId,
|
|
82
|
+
});
|
|
83
|
+
hook = revnetHook !== viem_1.zeroAddress ? revnetHook : null;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
const { ruleset, metadata } = await (0, rulesets_js_1.getCurrentRuleset)(client, {
|
|
87
|
+
chainId,
|
|
88
|
+
projectId,
|
|
89
|
+
});
|
|
90
|
+
const dataHook = metadata.dataHook;
|
|
91
|
+
if (metadata.useDataHookForPay && dataHook && dataHook !== viem_1.zeroAddress) {
|
|
92
|
+
const omni = juicebox_js_1.jbContractAddress["6"][contracts_js_1.JBOmnichainDeployerContracts.JBOmnichainDeployer]?.[chainId];
|
|
93
|
+
if (omni && dataHook.toLowerCase() === omni.toLowerCase()) {
|
|
94
|
+
// Omnichain project: the real 721 hook lives in the deployer's
|
|
95
|
+
// per-ruleset mapping.
|
|
96
|
+
const [omniHook] = await client.readContract({
|
|
97
|
+
address: omni,
|
|
98
|
+
abi: juicebox_js_1.jbOmnichainDeployerAbi,
|
|
99
|
+
functionName: "tiered721HookOf",
|
|
100
|
+
args: [projectId, BigInt(ruleset.id)],
|
|
101
|
+
});
|
|
102
|
+
hook = omniHook !== viem_1.zeroAddress ? omniHook : null;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Single-chain custom project: the data hook may be the 721 hook itself.
|
|
106
|
+
hook = dataHook;
|
|
107
|
+
authoritative = false;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
if (!hook)
|
|
112
|
+
return null;
|
|
113
|
+
// 2. The hook's store. For a non-authoritative candidate a revert means "not a
|
|
114
|
+
// 721 hook" (no shop); for an authoritative one, let failures throw.
|
|
115
|
+
const readStore = () => client.readContract({
|
|
116
|
+
address: hook,
|
|
117
|
+
abi: juicebox_js_1.jb721TiersHookAbi,
|
|
118
|
+
functionName: "STORE",
|
|
119
|
+
});
|
|
120
|
+
const store = authoritative
|
|
121
|
+
? await readStore()
|
|
122
|
+
: await readStore().catch(() => null);
|
|
123
|
+
if (!store)
|
|
124
|
+
return null;
|
|
125
|
+
// 3. Metadata id target + pricing context. Pricing is meaningless without the
|
|
126
|
+
// hook's exact currency + decimals, so a failure here is an error, not a
|
|
127
|
+
// fallback.
|
|
128
|
+
const [metadataIdTarget, pricingRaw] = await Promise.all([
|
|
129
|
+
get721MetadataIdTarget(client, { chainId, hook }),
|
|
130
|
+
client.readContract({
|
|
131
|
+
address: hook,
|
|
132
|
+
abi: juicebox_js_1.jb721TiersHookAbi,
|
|
133
|
+
functionName: "pricingContext",
|
|
134
|
+
}),
|
|
135
|
+
]);
|
|
136
|
+
// 4. The tiers, with resolver URIs included so callers can name tiers without
|
|
137
|
+
// a per-tier resolver read.
|
|
138
|
+
const raw = await client.readContract({
|
|
139
|
+
address: store,
|
|
140
|
+
abi: juicebox_js_1.jb721TiersHookStoreAbi,
|
|
141
|
+
functionName: "tiersOf",
|
|
142
|
+
args: [hook, categories, true, 0n, BigInt(tierLimit)],
|
|
143
|
+
});
|
|
144
|
+
const tiers = raw
|
|
145
|
+
.filter((tier) => tier.initialSupply > 0)
|
|
146
|
+
.map((tier) => ({
|
|
147
|
+
id: tier.id,
|
|
148
|
+
price: tier.price,
|
|
149
|
+
remainingSupply: tier.remainingSupply,
|
|
150
|
+
initialSupply: tier.initialSupply,
|
|
151
|
+
votingUnits: tier.votingUnits,
|
|
152
|
+
reserveFrequency: tier.reserveFrequency,
|
|
153
|
+
category: tier.category,
|
|
154
|
+
discountPercent: tier.discountPercent,
|
|
155
|
+
encodedIpfsUri: tier.encodedIpfsUri,
|
|
156
|
+
resolvedUri: tier.resolvedUri ?? "",
|
|
157
|
+
}));
|
|
158
|
+
return {
|
|
159
|
+
hook,
|
|
160
|
+
store,
|
|
161
|
+
metadataIdTarget,
|
|
162
|
+
pricing: { currency: Number(pricingRaw[0]), decimals: Number(pricingRaw[1]) },
|
|
163
|
+
tiers,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
//# 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":""}
|