@ickb/sdk 1000.0.82 → 9000.0.1

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.
Files changed (157) hide show
  1. package/README.md +81 -32
  2. package/dist/constants.d.ts +13 -22
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +80 -76
  5. package/dist/constants.js.map +1 -1
  6. package/dist/conversion/estimate.d.ts +39 -0
  7. package/dist/conversion/estimate.d.ts.map +1 -0
  8. package/dist/conversion/estimate.js +117 -0
  9. package/dist/conversion/estimate.js.map +1 -0
  10. package/dist/conversion/maturity.d.ts +15 -0
  11. package/dist/conversion/maturity.d.ts.map +1 -0
  12. package/dist/conversion/maturity.js +112 -0
  13. package/dist/conversion/maturity.js.map +1 -0
  14. package/dist/conversion/plans.d.ts +20 -0
  15. package/dist/conversion/plans.d.ts.map +1 -0
  16. package/dist/conversion/plans.js +106 -0
  17. package/dist/conversion/plans.js.map +1 -0
  18. package/dist/conversion/projection.d.ts +22 -0
  19. package/dist/conversion/projection.d.ts.map +1 -0
  20. package/dist/conversion/projection.js +91 -0
  21. package/dist/conversion/projection.js.map +1 -0
  22. package/dist/conversion/types.d.ts +252 -0
  23. package/dist/conversion/types.d.ts.map +1 -0
  24. package/dist/conversion/types.js +2 -0
  25. package/dist/conversion/types.js.map +1 -0
  26. package/dist/conversion/withdrawal_ring.d.ts +36 -0
  27. package/dist/conversion/withdrawal_ring.d.ts.map +1 -0
  28. package/dist/conversion/withdrawal_ring.js +87 -0
  29. package/dist/conversion/withdrawal_ring.js.map +1 -0
  30. package/dist/dao.d.ts +86 -0
  31. package/dist/dao.d.ts.map +1 -0
  32. package/dist/dao.js +113 -0
  33. package/dist/dao.js.map +1 -0
  34. package/dist/index.d.ts +51 -3
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +20 -3
  37. package/dist/index.js.map +1 -1
  38. package/dist/logic.d.ts +85 -0
  39. package/dist/logic.d.ts.map +1 -0
  40. package/dist/logic.js +184 -0
  41. package/dist/logic.js.map +1 -0
  42. package/dist/order/cells.d.ts +207 -0
  43. package/dist/order/cells.d.ts.map +1 -0
  44. package/dist/order/cells.js +427 -0
  45. package/dist/order/cells.js.map +1 -0
  46. package/dist/order/conversion.d.ts +43 -0
  47. package/dist/order/conversion.d.ts.map +1 -0
  48. package/dist/order/conversion.js +123 -0
  49. package/dist/order/conversion.js.map +1 -0
  50. package/dist/order/fee.d.ts +9 -0
  51. package/dist/order/fee.d.ts.map +1 -0
  52. package/dist/order/fee.js +24 -0
  53. package/dist/order/fee.js.map +1 -0
  54. package/dist/order/fill.d.ts +36 -0
  55. package/dist/order/fill.d.ts.map +1 -0
  56. package/dist/order/fill.js +53 -0
  57. package/dist/order/fill.js.map +1 -0
  58. package/dist/order/info.d.ts +62 -0
  59. package/dist/order/info.d.ts.map +1 -0
  60. package/dist/order/info.js +99 -0
  61. package/dist/order/info.js.map +1 -0
  62. package/dist/order/master.d.ts +49 -0
  63. package/dist/order/master.d.ts.map +1 -0
  64. package/dist/order/master.js +27 -0
  65. package/dist/order/master.js.map +1 -0
  66. package/dist/order/matcher.d.ts +43 -0
  67. package/dist/order/matcher.d.ts.map +1 -0
  68. package/dist/order/matcher.js +123 -0
  69. package/dist/order/matcher.js.map +1 -0
  70. package/dist/order/order.d.ts +59 -0
  71. package/dist/order/order.d.ts.map +1 -0
  72. package/dist/order/order.js +239 -0
  73. package/dist/order/order.js.map +1 -0
  74. package/dist/order/order_data.d.ts +51 -0
  75. package/dist/order/order_data.d.ts.map +1 -0
  76. package/dist/order/order_data.js +64 -0
  77. package/dist/order/order_data.js.map +1 -0
  78. package/dist/order/ratio.d.ts +42 -0
  79. package/dist/order/ratio.d.ts.map +1 -0
  80. package/dist/order/ratio.js +82 -0
  81. package/dist/order/ratio.js.map +1 -0
  82. package/dist/order/relative.d.ts +43 -0
  83. package/dist/order/relative.d.ts.map +1 -0
  84. package/dist/order/relative.js +54 -0
  85. package/dist/order/relative.js.map +1 -0
  86. package/dist/owned_owner.d.ts +113 -0
  87. package/dist/owned_owner.d.ts.map +1 -0
  88. package/dist/owned_owner.js +280 -0
  89. package/dist/owned_owner.js.map +1 -0
  90. package/dist/sdk.d.ts +71 -42
  91. package/dist/sdk.d.ts.map +1 -1
  92. package/dist/sdk.js +388 -209
  93. package/dist/sdk.js.map +1 -1
  94. package/dist/send/sign_and_send_transaction.d.ts +46 -0
  95. package/dist/send/sign_and_send_transaction.d.ts.map +1 -0
  96. package/dist/send/sign_and_send_transaction.js +101 -0
  97. package/dist/send/sign_and_send_transaction.js.map +1 -0
  98. package/dist/send/wait_transaction.d.ts +41 -0
  99. package/dist/send/wait_transaction.d.ts.map +1 -0
  100. package/dist/send/wait_transaction.js +204 -0
  101. package/dist/send/wait_transaction.js.map +1 -0
  102. package/dist/udt.d.ts +123 -0
  103. package/dist/udt.d.ts.map +1 -0
  104. package/dist/udt.js +244 -0
  105. package/dist/udt.js.map +1 -0
  106. package/dist/utils/chain.d.ts +38 -0
  107. package/dist/utils/chain.d.ts.map +1 -0
  108. package/dist/utils/chain.js +20 -0
  109. package/dist/utils/chain.js.map +1 -0
  110. package/dist/utils/codec.d.ts +19 -0
  111. package/dist/utils/codec.d.ts.map +1 -0
  112. package/dist/utils/codec.js +66 -0
  113. package/dist/utils/codec.js.map +1 -0
  114. package/dist/utils/transaction_header.d.ts +17 -0
  115. package/dist/utils/transaction_header.d.ts.map +1 -0
  116. package/dist/utils/transaction_header.js +44 -0
  117. package/dist/utils/transaction_header.js.map +1 -0
  118. package/dist/utils/utils.d.ts +126 -0
  119. package/dist/utils/utils.d.ts.map +1 -0
  120. package/dist/utils/utils.js +151 -0
  121. package/dist/utils/utils.js.map +1 -0
  122. package/package.json +19 -26
  123. package/src/constants.ts +84 -181
  124. package/src/conversion/estimate.ts +157 -0
  125. package/src/conversion/maturity.ts +159 -0
  126. package/src/conversion/plans.ts +144 -0
  127. package/src/conversion/projection.ts +128 -0
  128. package/src/conversion/types.ts +287 -0
  129. package/src/conversion/withdrawal_ring.ts +126 -0
  130. package/src/dao.ts +172 -0
  131. package/src/index.ts +89 -3
  132. package/src/logic.ts +295 -0
  133. package/src/order/cells.ts +520 -0
  134. package/src/order/conversion.ts +173 -0
  135. package/src/order/fee.ts +30 -0
  136. package/src/order/fill.ts +83 -0
  137. package/src/order/info.ts +178 -0
  138. package/src/order/master.ts +42 -0
  139. package/src/order/matcher.ts +191 -0
  140. package/src/order/order.ts +302 -0
  141. package/src/order/order_data.ts +128 -0
  142. package/src/order/ratio.ts +144 -0
  143. package/src/order/relative.ts +106 -0
  144. package/src/owned_owner.ts +394 -0
  145. package/src/sdk.ts +555 -440
  146. package/src/send/sign_and_send_transaction.ts +120 -0
  147. package/src/send/wait_transaction.ts +271 -0
  148. package/src/udt.ts +317 -0
  149. package/src/utils/chain.ts +43 -0
  150. package/src/utils/codec.ts +74 -0
  151. package/src/utils/transaction_header.ts +66 -0
  152. package/src/utils/utils.ts +237 -0
  153. package/dist/codec.d.ts +0 -3
  154. package/dist/codec.d.ts.map +0 -1
  155. package/dist/codec.js +0 -58
  156. package/dist/codec.js.map +0 -1
  157. package/src/codec.ts +0 -138
@@ -0,0 +1,151 @@
1
+ import { ccc } from "@ckb-ccc/core";
2
+ /**
3
+ * The default page size used when querying cells from the chain.
4
+ *
5
+ * This page size is aligned with Nervos CKB's pull request #4576
6
+ * (https://github.com/nervosnetwork/ckb/pull/4576) to avoid excessive paging.
7
+ */
8
+ export const defaultCellPageSize = 400;
9
+ /**
10
+ * Reads every committed cell matching the key, page by page, without touching
11
+ * CCC's cell cache. The scan ends on the first short page.
12
+ *
13
+ * @remarks A full page must advance the cursor; otherwise the read throws so a faulty
14
+ * endpoint in the app's public node pool cannot keep the scan looping forever.
15
+ * The cursor continues ordering, not a coherent snapshot. There is no aggregate budget:
16
+ * a large book costs a slower read rather than a partial result.
17
+ */
18
+ export async function findCells(client, keyLike) {
19
+ const key = ccc.ClientIndexerSearchKey.from(keyLike);
20
+ const cells = [];
21
+ let after;
22
+ for (;;) {
23
+ const page = await client.findCellsPagedNoCache(key, "asc", defaultCellPageSize, after);
24
+ cells.push(...page.cells);
25
+ if (page.cells.length < defaultCellPageSize) {
26
+ return cells;
27
+ }
28
+ if (page.lastCursor === after) {
29
+ throw new Error("Cell scan cursor did not advance");
30
+ }
31
+ after = page.lastCursor;
32
+ }
33
+ }
34
+ /**
35
+ * True when a cell has no type script and no data payload.
36
+ *
37
+ * @remarks
38
+ * This is a structural filter for plain capacity cells. Spendability still
39
+ * depends on the lock script, live cell state, and transaction context.
40
+ */
41
+ export function isPlainCapacityCell(cell) {
42
+ return cell.cellOutput.type === undefined && cell.outputData === "0x";
43
+ }
44
+ /**
45
+ * Performs asynchronously a binary search to find the smallest index `i` in the range [0, n)
46
+ * such that the function `f(i)` returns true. It is assumed that for the range
47
+ * [0, n), if `f(i)` is true, then `f(i+1)` is also true. This means that there
48
+ * is a prefix of the input range where `f` is false, followed by a suffix where
49
+ * `f` is true. If no such index exists, the function returns `n`.
50
+ *
51
+ * The function `f` is only called for indices in the range [0, n).
52
+ *
53
+ * @param n - The non-negative integer upper bound of the search range (exclusive).
54
+ * @param f - An async function that takes an index `i` and returns a boolean value.
55
+ * @returns The smallest index `i` such that `f(i)` is true, or `n` if no such index exists.
56
+ *
57
+ * @remarks Adapted from Go's standard library search implementation:
58
+ * {@link https://go.dev/src/sort/search.go}
59
+ */
60
+ export async function asyncBinarySearch(n, f) {
61
+ // Define f(-1) == false and f(n) == true.
62
+ // Invariant: f(i-1) == false, f(j) == true.
63
+ let [i, j] = [0, n];
64
+ while (i < j) {
65
+ const h = Math.trunc((i + j) / 2);
66
+ // i ≤ h < j
67
+ if (!(await f(h))) {
68
+ i = h + 1; // preserves f(i-1) == false
69
+ }
70
+ else {
71
+ j = h; // preserves f(j) == true
72
+ }
73
+ }
74
+ // i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
75
+ return i;
76
+ }
77
+ /**
78
+ * The client's JSON-RPC requestor, when it has one. The connector hands the interface a
79
+ * composition proxy over the public client (`ClientWithFeeRate`, a `ccc.Client` but not a
80
+ * `ccc.ClientJsonRpc`), so `instanceof` misses it; the proxy forwards the property.
81
+ */
82
+ export function jsonRpcRequestor(client) {
83
+ if (!("requestor" in client)) {
84
+ return undefined;
85
+ }
86
+ const { requestor } = client;
87
+ return requestor instanceof ccc.RequestorJsonRpc ? requestor : undefined;
88
+ }
89
+ /** A node's raw `get_transaction` status record (verbosity 1), the fields the stack reads. */
90
+ export function rawTransactionStatus(response) {
91
+ const record = typeof response === "object" &&
92
+ response !== null &&
93
+ "tx_status" in response &&
94
+ typeof response.tx_status === "object" &&
95
+ response.tx_status !== null
96
+ ? response.tx_status
97
+ : {};
98
+ return {
99
+ status: "status" in record && typeof record.status === "string" ? record.status : undefined,
100
+ reason: "reason" in record && typeof record.reason === "string" ? record.reason : undefined,
101
+ blockNumber: "block_number" in record && typeof record.block_number === "string"
102
+ ? ccc.numFrom(record.block_number)
103
+ : undefined,
104
+ };
105
+ }
106
+ export function minBigInt(left, right) {
107
+ return left < right ? left : right;
108
+ }
109
+ export function maxBigInt(left, right) {
110
+ return left > right ? left : right;
111
+ }
112
+ /** `numerator / denominator` rounded up; the denominator is positive. */
113
+ export function ceilDiv(numerator, denominator) {
114
+ return (numerator + denominator - 1n) / denominator;
115
+ }
116
+ /**
117
+ * Compares two bigint values using sort-compatible ordering.
118
+ *
119
+ * @returns `-1` when `left` is smaller, `1` when `left` is larger, and `0` when equal.
120
+ */
121
+ export function compareBigInt(left, right) {
122
+ if (left < right) {
123
+ return -1;
124
+ }
125
+ if (left > right) {
126
+ return 1;
127
+ }
128
+ return 0;
129
+ }
130
+ /**
131
+ * Yields unique items from the given iterable based on their hex representation.
132
+ *
133
+ * The function uses a Set to track the hex-string keys of items that have already been yielded.
134
+ * Only the first occurrence of each unique key is yielded.
135
+ *
136
+ * @typeParam T - A type that extends ccc.Entity.
137
+ * @param items - An iterable collection of items of type T.
138
+ * @returns A generator that yields items from the iterable, ensuring that each item's
139
+ * hex representation (via toHex()) is unique.
140
+ */
141
+ export function* unique(items) {
142
+ const set = new Set();
143
+ for (const i of items) {
144
+ const key = i.toHex();
145
+ if (!set.has(key)) {
146
+ set.add(key);
147
+ yield i;
148
+ }
149
+ }
150
+ }
151
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ickb/sdk",
3
- "version": "1000.0.82",
3
+ "version": "9000.0.1",
4
4
  "description": "iCKB SDK built on top of CCC",
5
5
  "keywords": [
6
6
  "ickb",
@@ -10,52 +10,45 @@
10
10
  ],
11
11
  "author": "phroi",
12
12
  "license": "MIT",
13
- "homepage": "https://github.com/ickb/sdk",
13
+ "homepage": "https://ickb.org",
14
14
  "repository": {
15
15
  "type": "git",
16
- "url": "https://github.com/ickb/sdk"
16
+ "url": "git+https://github.com/ickb/stack.git"
17
17
  },
18
18
  "bugs": {
19
- "url": "https://github.com/ickb/sdk/issues"
19
+ "url": "https://github.com/ickb/stack/issues"
20
20
  },
21
21
  "sideEffects": false,
22
22
  "type": "module",
23
+ "engines": {
24
+ "node": ">=26"
25
+ },
23
26
  "main": "dist/index.js",
24
27
  "types": "dist/index.d.ts",
25
28
  "exports": {
26
29
  ".": {
27
- "import": "./dist/index.js",
28
- "types": "./dist/index.d.ts"
30
+ "types": "./dist/index.d.ts",
31
+ "import": "./dist/index.js"
29
32
  }
30
33
  },
31
- "engines": {
32
- "node": ">=18"
33
- },
34
34
  "files": [
35
35
  "dist",
36
36
  "src"
37
37
  ],
38
38
  "publishConfig": {
39
- "access": "public",
40
- "provenance": true
41
- },
42
- "devDependencies": {
43
- "@eslint/js": "^9.29.0",
44
- "eslint": "^9.29.0",
45
- "prettier": "^3.5.3",
46
- "typescript": "^5.8.3",
47
- "typescript-eslint": "^8.34.0"
39
+ "access": "public"
48
40
  },
49
41
  "dependencies": {
50
- "@ckb-ccc/core": "canary",
51
- "@ickb/core": "^1000.0.82",
52
- "@ickb/dao": "^1000.0.82",
53
- "@ickb/order": "^1000.0.82",
54
- "@ickb/utils": "^1000.0.82"
42
+ "@ckb-ccc/core": "^1.23.0"
43
+ },
44
+ "devDependencies": {
45
+ "@ickb/testkit": "9000.0.0",
46
+ "@typescript/native-preview": "7.0.0-dev.20260707.2"
55
47
  },
56
48
  "scripts": {
57
- "lint": "eslint ./src",
58
- "clean": "rm -fr pnpm-lock.yaml dist/*",
59
- "revamp": "pnpm clean; pnpm up && node dist/index.js && pnpm lint"
49
+ "test": "vitest",
50
+ "build": "rm -fr dist && tsgo -p tsconfig.build.json && node ../scripts/tooling/build/rewrite-dts-imports.ts dist",
51
+ "lint:api": "api-extractor run",
52
+ "lint:publish": "publint --strict --pack pnpm"
60
53
  }
61
54
  }
package/src/constants.ts CHANGED
@@ -1,205 +1,108 @@
1
1
  import { ccc } from "@ckb-ccc/core";
2
- import { IckbUdtManager, LogicManager, OwnedOwnerManager } from "@ickb/core";
3
- import { DaoManager } from "@ickb/dao";
4
- import { OrderManager } from "@ickb/order";
5
- import { CapacityManager, unique, type ScriptDeps } from "@ickb/utils";
2
+ import type { SdkManagers } from "./conversion/types.ts";
3
+ import { LogicManager } from "./logic.ts";
4
+ import { OrderManager } from "./order/order.ts";
5
+ import { OwnedOwnerManager } from "./owned_owner.ts";
6
+ import { IckbUdt } from "./udt.ts";
7
+ import type { SupportedChain } from "./utils/chain.ts";
6
8
 
7
- /**
8
- * Retrieves the configuration for the given deployment environment.
9
- *
10
- * Accepts either a string identifier ("mainnet" or "testnet") or a custom configuration
11
- * object containing script dependencies for a devnet.
12
- *
13
- * It sets up various managers (UDT, Logic, OwnedOwner, Order, Dao, Capacity) and also
14
- * aggregates a unique list of known bot scripts.
15
- *
16
- * @param d - Either a network identifier ("mainnet"/"testnet") or an object containing
17
- * explicit script dependencies for devnet.
18
- * @param bots - An optional array of bot script-like objects to augment the list of known bots.
19
- * @returns An object containing the instantiated managers and bots.
20
- */
21
- export function getConfig(
22
- d:
23
- | "mainnet"
24
- | "testnet"
25
- | {
26
- // For devnet configuration provide explicit script dependencies.
27
- udt: ScriptDeps;
28
- logic: ScriptDeps;
29
- ownedOwner: ScriptDeps;
30
- order: ScriptDeps;
31
- dao: ScriptDeps;
32
- },
33
- bots: ccc.ScriptLike[] = [],
34
- ): {
35
- managers: {
36
- capacity: CapacityManager;
37
- dao: DaoManager;
38
- ickbUdt: IckbUdtManager;
39
- logic: LogicManager;
40
- ownedOwner: OwnedOwnerManager;
41
- order: OrderManager;
42
- };
43
- bots: ccc.Script[];
44
- } {
45
- // If deps is provided as a network string, use the pre-defined constants.
46
- if (d === "mainnet" || d === "testnet") {
47
- bots = bots.concat(
48
- d === "mainnet" ? MAINNET_KNOWN_BOTS : TESTNET_KNOWN_BOTS,
49
- );
50
- const depGroup = d === "mainnet" ? MAINNET_DEP_GROUP : TESTNET_DEP_GROUP;
51
- d = {
52
- udt: from(UDT, depGroup),
53
- logic: from(ICKB_LOGIC, depGroup),
54
- ownedOwner: from(OWNED_OWNER, depGroup),
55
- order: from(ORDER, depGroup),
56
- dao: from(DAO, depGroup),
57
- };
58
- }
59
-
60
- const capacity = CapacityManager.withAnyData();
61
- const dao = new DaoManager(d.dao.script, d.dao.cellDeps);
62
- const ickbUdt = new IckbUdtManager(
63
- d.udt.script,
64
- d.udt.cellDeps,
65
- d.logic.script,
66
- dao,
67
- );
68
- const logic = new LogicManager(
69
- d.logic.script,
70
- d.logic.cellDeps,
71
- dao,
72
- ickbUdt,
73
- );
74
- const ownedOwner = new OwnedOwnerManager(
75
- d.ownedOwner.script,
76
- d.ownedOwner.cellDeps,
77
- dao,
78
- ickbUdt,
79
- );
80
- const order = new OrderManager(d.order.script, d.order.cellDeps, ickbUdt);
81
-
82
- return {
83
- managers: {
84
- capacity,
85
- dao,
86
- ickbUdt,
87
- logic,
88
- ownedOwner,
89
- order,
90
- },
91
- bots: [...unique(bots.map((b) => ccc.Script.from(b)))],
92
- };
93
- }
94
-
95
- /**
96
- * Wraps a script-like object into a ScriptDeps structure.
97
- *
98
- * @param script - The script or script-like object.
99
- * @param cellDeps - Additional cell dependencies that the script may require.
100
- * @returns An object containing the script and its associated cell dependencies.
101
- */
102
- function from(script: ccc.ScriptLike, ...cellDeps: ccc.CellDep[]): ScriptDeps {
103
- return {
104
- script: ccc.Script.from(script),
105
- cellDeps,
106
- };
107
- }
108
-
109
- /**
110
- * DAO (Decentralized Autonomous Organization) lock script information.
111
- */
112
- const DAO = {
113
- codeHash:
114
- "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e",
9
+ /** Nervos DAO type script. */
10
+ const DAO = ccc.Script.from({
11
+ codeHash: "0x82d76d1b75fe2fd9a27dfbaa65a039221a380d76c926f378d3f81cf3e7e13f2e",
115
12
  hashType: "type",
116
13
  args: "0x",
117
- };
14
+ });
118
15
 
119
- /**
120
- * UDT (User Defined Token) lock script information used for onchain validation.
121
- */
122
- const UDT = {
123
- codeHash:
124
- "0x50bd8d6680b8b9cf98b73f3c08faf8b2a21914311954118ad6609be6e78a1b95",
16
+ /** Raw xUDT type script; the iCKB args are computed by `IckbUdt.typeScriptFrom`. */
17
+ const UDT = ccc.Script.from({
18
+ codeHash: "0x50bd8d6680b8b9cf98b73f3c08faf8b2a21914311954118ad6609be6e78a1b95",
125
19
  hashType: "data1",
126
- args: "0xb73b6ab39d79390c6de90a09c96b290c331baf1798ed6f97aed02590929734e800000080",
127
- };
20
+ args: "0x",
21
+ });
128
22
 
129
- /**
130
- * Logic script information for the iCKB logic contract.
131
- */
132
- const ICKB_LOGIC = {
133
- codeHash:
134
- "0x2a8100ab5990fa055ab1b50891702e1e895c7bd1df6322cd725c1a6115873bd3",
23
+ /** iCKB Logic script. */
24
+ const ICKB_LOGIC = ccc.Script.from({
25
+ codeHash: "0x2a8100ab5990fa055ab1b50891702e1e895c7bd1df6322cd725c1a6115873bd3",
135
26
  hashType: "data1",
136
27
  args: "0x",
137
- };
28
+ });
138
29
 
139
- /**
140
- * OwnedOwner lock script information.
141
- */
142
- const OWNED_OWNER = {
143
- codeHash:
144
- "0xacc79e07d107831feef4c70c9e683dac5644d5993b9cb106dca6e74baa381bd0",
30
+ /** Owned Owner lock script. */
31
+ const OWNED_OWNER = ccc.Script.from({
32
+ codeHash: "0xacc79e07d107831feef4c70c9e683dac5644d5993b9cb106dca6e74baa381bd0",
145
33
  hashType: "data1",
146
34
  args: "0x",
147
- };
35
+ });
148
36
 
149
- /**
150
- * Order lock script information.
151
- */
152
- const ORDER = {
153
- codeHash:
154
- "0x49dfb6afee5cc8ac4225aeea8cb8928b150caf3cd92fea33750683c74b13254a",
37
+ /** Order lock script. */
38
+ const ORDER = ccc.Script.from({
39
+ codeHash: "0x49dfb6afee5cc8ac4225aeea8cb8928b150caf3cd92fea33750683c74b13254a",
155
40
  hashType: "data1",
156
41
  args: "0x",
157
- };
158
-
159
- /**
160
- * Mainnet dependency group cell dep.
161
- */
162
- const MAINNET_DEP_GROUP = ccc.CellDep.from({
163
- outPoint: {
164
- txHash:
165
- "0x621a6f38de3b9f453016780edac3b26bfcbfa3e2ecb47c2da275471a5d3ed165",
166
- index: "0x0",
167
- },
168
- depType: "depGroup",
169
42
  });
170
43
 
171
- /**
172
- * Testnet dependency group cell dep.
173
- */
174
- const TESTNET_DEP_GROUP = ccc.CellDep.from({
175
- outPoint: {
176
- txHash:
177
- "0xf7ece4fb33d8378344cab11fcd6a4c6f382fd4207ac921cf5821f30712dcd311",
178
- index: "0x0",
44
+ /** Each network's code cells, given as direct code deps, and the dep group of the rest. */
45
+ const DEPLOYMENTS = {
46
+ mainnet: {
47
+ udtCode: {
48
+ txHash: "0xc07844ce21b38e4b071dd0e1ee3b0e27afd8d7532491327f39b786343f558ab7",
49
+ index: 0,
50
+ },
51
+ logicCode: {
52
+ txHash: "0xd7309191381f5a8a2904b8a79958a9be2752dbba6871fa193dab6aeb29dc8f44",
53
+ index: 0,
54
+ },
55
+ depGroup: {
56
+ txHash: "0x621a6f38de3b9f453016780edac3b26bfcbfa3e2ecb47c2da275471a5d3ed165",
57
+ index: 0,
58
+ },
179
59
  },
180
- depType: "depGroup",
181
- });
60
+ testnet: {
61
+ udtCode: {
62
+ txHash: "0xbf6fb538763efec2a70a6a3dcb7242787087e1030c4e7d86585bc63a9d337f5f",
63
+ index: 0,
64
+ },
65
+ logicCode: {
66
+ txHash: "0x9ac989b3355764f76cdce02c69dedb819fdfbcbda49a7db1a2c9facdfdb9a7fe",
67
+ index: 0,
68
+ },
69
+ depGroup: {
70
+ txHash: "0xf7ece4fb33d8378344cab11fcd6a4c6f382fd4207ac921cf5821f30712dcd311",
71
+ index: 0,
72
+ },
73
+ },
74
+ } as const;
182
75
 
183
76
  /**
184
- * Array of known bot scripts on the mainnet.
77
+ * Plain CKB the bot keeps for its own cells and fees: its sizing line for matches and deposits.
185
78
  */
186
- const MAINNET_KNOWN_BOTS = [
187
- {
188
- codeHash:
189
- "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
190
- hashType: "type",
191
- args: "0xd096cb29e2f68a85a46bd6bf6cbee6327959ba64",
192
- },
193
- ];
79
+ export const CKB_RESERVE = ccc.fixedPointFrom(1000);
194
80
 
195
81
  /**
196
- * Array of known bot scripts on the testnet.
82
+ * The managers of one network's iCKB deployment.
83
+ *
84
+ * @remarks Builders still return partial transactions. `IckbSdk` owns the shared iCKB
85
+ * completion path as `sdk.completeTransaction(...)`, which callers invoke before send.
197
86
  */
198
- const TESTNET_KNOWN_BOTS = [
199
- {
200
- codeHash:
201
- "0x9bd7e06f3ecf4be0f2fcd2188b23f1b9fcc88e5d4b65a8637b17723bbda3cce8",
202
- hashType: "type",
203
- args: "0xb4380110f7679ac31cefe4925485645d82bf619f",
204
- },
205
- ];
87
+ export function getConfig(chain: SupportedChain): SdkManagers {
88
+ // The runtime check stands for callers outside TypeScript.
89
+ if (!Object.hasOwn(DEPLOYMENTS, chain)) {
90
+ throw new TypeError("unsupported iCKB network");
91
+ }
92
+ const { udtCode, logicCode, depGroup } = DEPLOYMENTS[chain];
93
+ const cellDeps = [ccc.CellDep.from({ outPoint: depGroup, depType: "depGroup" })];
94
+ const dao = { script: DAO, cellDeps };
95
+ const ickbUdt = new IckbUdt({
96
+ code: udtCode,
97
+ script: IckbUdt.typeScriptFrom(UDT, ICKB_LOGIC),
98
+ logicCode,
99
+ logicScript: ICKB_LOGIC,
100
+ daoScript: DAO,
101
+ });
102
+ return {
103
+ ickbUdt,
104
+ ownedOwner: new OwnedOwnerManager(OWNED_OWNER, cellDeps, dao),
105
+ ickbLogic: new LogicManager(ICKB_LOGIC, cellDeps, dao),
106
+ order: new OrderManager(ORDER, cellDeps, ickbUdt.script),
107
+ };
108
+ }
@@ -0,0 +1,157 @@
1
+ import type { IckbDepositCell } from "../logic.ts";
2
+ import {
3
+ OrderConversionRepresentabilityError,
4
+ quoteConversion,
5
+ } from "../order/conversion.ts";
6
+ import { ceilDiv, type ValueComponents } from "../utils/utils.ts";
7
+ import { maturity } from "./maturity.ts";
8
+ import type { ConversionOrderEstimate, SystemState } from "./types.ts";
9
+
10
+ /**
11
+ * Default order fee: 0.01%. At roughly 2% annual DAO yield this buys about two days of
12
+ * price headroom for a buy, versus hours at 0.001%; actual fillability also depends on
13
+ * mining fees. It leaves time to notice a stalled bot without charging the much larger 0.1%.
14
+ */
15
+ export const DEFAULT_ORDER_FEE = 10n;
16
+
17
+ /** Default order-fee denominator used by Stack conversion quotes and plans. */
18
+ export const DEFAULT_ORDER_FEE_BASE = 100000n;
19
+
20
+ /** The quote and its maturity estimate, or `undefined` when no order ratio represents it. */
21
+ export function estimateConversionOrder(
22
+ isCkb2Udt: boolean,
23
+ amounts: ValueComponents,
24
+ system: SystemState,
25
+ { fee, feeBase }: { fee: bigint; feeBase: bigint },
26
+ takenDeposits: readonly IckbDepositCell[] = [],
27
+ ): ConversionOrderEstimate | undefined {
28
+ let quote: ReturnType<typeof quoteConversion>;
29
+ try {
30
+ quote = quoteConversion(isCkb2Udt, system.exchangeRatio, amounts, { fee, feeBase });
31
+ } catch (error) {
32
+ if (error instanceof OrderConversionRepresentabilityError) {
33
+ return undefined;
34
+ }
35
+ throw error;
36
+ }
37
+ const estimatedMaturity =
38
+ quote.ckbFee >= estimateMaturityFeeThreshold(system)
39
+ ? maturity({ info: quote.info, amounts }, system, takenDeposits)
40
+ : undefined;
41
+ return { ...quote, maturity: estimatedMaturity };
42
+ }
43
+
44
+ /**
45
+ * Returns the CKB fee threshold above which order maturity is worth estimating.
46
+ * This conservative proxy stays separate from partialOrderFee: the quote has no built
47
+ * order whose serialized size could supply that fee yet.
48
+ */
49
+ export function estimateMaturityFeeThreshold(
50
+ system: Pick<SystemState, "feeRate">,
51
+ ): bigint {
52
+ return 10n * system.feeRate;
53
+ }
54
+
55
+ /**
56
+ * The smallest request one direction accepts as an order at the current fee rate. A
57
+ * CKB-to-iCKB remainder pays the default order fee, which must cover the maturity threshold
58
+ * of ten mining fees; an iCKB-to-CKB remainder can give its whole CKB value as the dust
59
+ * fee, so its value must exceed the threshold. The extra unit covers the quote's rounding,
60
+ * as the dust search's boundary shows; callers round up further for display.
61
+ */
62
+ export function minimumOrderAmount(isCkb2Udt: boolean, system: SystemState): bigint {
63
+ const threshold = estimateMaturityFeeThreshold(system) + 1n;
64
+ if (isCkb2Udt) {
65
+ return ceilDiv(threshold * DEFAULT_ORDER_FEE_BASE, DEFAULT_ORDER_FEE);
66
+ }
67
+ const { ckbScale, udtScale } = system.exchangeRatio;
68
+ return ceilDiv(threshold * ckbScale, udtScale);
69
+ }
70
+
71
+ /**
72
+ * The order leg of an iCKB-to-CKB conversion: at the default fee when that fee clears the
73
+ * maturity threshold, else the smallest fee that does (a dust order, noticed). Either way
74
+ * it is dated: a sell order at par is always covered by the pool (see `maturity`).
75
+ */
76
+ export function estimateIckbToCkbOrder(
77
+ amounts: ValueComponents,
78
+ system: SystemState,
79
+ takenDeposits: readonly IckbDepositCell[],
80
+ ): (ConversionOrderEstimate & { maturity: bigint }) | undefined {
81
+ const base = estimateConversionOrder(
82
+ false,
83
+ amounts,
84
+ system,
85
+ { fee: DEFAULT_ORDER_FEE, feeBase: DEFAULT_ORDER_FEE_BASE },
86
+ takenDeposits,
87
+ );
88
+ if (base?.maturity !== undefined) {
89
+ return { ...base, maturity: base.maturity };
90
+ }
91
+
92
+ const dust = estimateDustIckbToCkbOrder(amounts, system);
93
+ if (dust === undefined) {
94
+ return undefined;
95
+ }
96
+ return {
97
+ ...dust,
98
+ maturity: maturity({ info: dust.info, amounts }, system, takenDeposits),
99
+ notice: {
100
+ inputIckb: amounts.udtValue,
101
+ outputCkb: dust.convertedAmount,
102
+ incentiveCkb: positiveFee(dust.ckbFee),
103
+ },
104
+ };
105
+ }
106
+
107
+ function estimateDustIckbToCkbOrder(
108
+ amounts: ValueComponents,
109
+ system: SystemState,
110
+ ): ConversionOrderEstimate | undefined {
111
+ const baseEstimate = estimateConversionOrder(false, amounts, system, {
112
+ fee: 0n,
113
+ feeBase: DEFAULT_ORDER_FEE_BASE,
114
+ });
115
+ if (baseEstimate === undefined) {
116
+ return undefined;
117
+ }
118
+ const targetFee = estimateMaturityFeeThreshold(system);
119
+ const feeBase = baseEstimate.convertedAmount + 1n;
120
+ if (targetFee <= 0n || feeBase <= 1n) {
121
+ return baseEstimate;
122
+ }
123
+ const estimateWithFee = (fee: bigint): ConversionOrderEstimate | undefined =>
124
+ estimateConversionOrder(false, amounts, system, { fee, feeBase });
125
+ return lowestFeeEstimateAtThreshold(estimateWithFee, feeBase - 1n, targetFee);
126
+ }
127
+
128
+ function lowestFeeEstimateAtThreshold(
129
+ estimateWithFee: (fee: bigint) => ConversionOrderEstimate | undefined,
130
+ highestFee: bigint,
131
+ targetFee: bigint,
132
+ ): ConversionOrderEstimate | undefined {
133
+ const highestDiscount = estimateWithFee(highestFee);
134
+ if (highestDiscount === undefined || highestDiscount.ckbFee < targetFee) {
135
+ return undefined;
136
+ }
137
+
138
+ let low = 0n;
139
+ let high = highestFee;
140
+ while (low < high) {
141
+ const mid = (low + high) / 2n;
142
+ const estimateAtMid = estimateWithFee(mid);
143
+ if (estimateAtMid === undefined) {
144
+ return undefined;
145
+ }
146
+ if (estimateAtMid.ckbFee >= targetFee) {
147
+ high = mid;
148
+ } else {
149
+ low = mid + 1n;
150
+ }
151
+ }
152
+ return estimateWithFee(low);
153
+ }
154
+
155
+ function positiveFee(fee: bigint): bigint {
156
+ return fee > 0n ? fee : 0n;
157
+ }