Skip to content

Commit 417bc46

Browse files
committed
feat: use a new udtRegister class to contain metadata register intention
1 parent 225ccb8 commit 417bc46

File tree

3 files changed

+131
-112
lines changed

3 files changed

+131
-112
lines changed

packages/udt/src/barrel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from "./udt/index.js";
22
export * from "./udtPausable/index.js";
3+
export * from "./udtRegister/index.js";

packages/udt/src/udt/index.ts

Lines changed: 0 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -189,29 +189,6 @@ export class UdtConfig {
189189
}
190190
}
191191

192-
/**
193-
* The basic metadata of a UDT token.
194-
*
195-
* @example
196-
* ```typescript
197-
* const metadataMolecule = UdtMetadata.encode({
198-
* name: "My UDT",
199-
* symbol: "MYUDT",
200-
* decimals: 8,
201-
* icon: "https://example.com/icon.png",
202-
* });
203-
* ```
204-
*
205-
* @public
206-
* @category UDT
207-
*/
208-
export const UdtMetadata = ccc.mol.table({
209-
name: ccc.mol.String,
210-
symbol: ccc.mol.String,
211-
decimals: ccc.mol.Uint8,
212-
icon: ccc.mol.String,
213-
});
214-
215192
/**
216193
* Represents a User Defined Token (UDT) script compliant with the SSRI protocol.
217194
*
@@ -345,95 +322,6 @@ export class Udt extends ssri.Trait {
345322
);
346323
}
347324

348-
/**
349-
* Registers (creates) a new UDT with on-chain metadata.
350-
* This method creates a new unique UDT instance (usually with a TypeId pattern),
351-
* assigns on-chain metadata (name, symbol, decimals, icon), and returns a transaction
352-
* to instantiate the new token. Often used by the deployer/owner.
353-
*
354-
* @param signer - The signer (owner) who will initialize and own the new UDT
355-
* @param metadata - Object containing UDT metadata (name, symbol, decimals, icon)
356-
* @param tx - Optional existing transaction to build upon
357-
* @returns Promise resolving to `{ tx, tokenHash }`, where `tx` is the deployment transaction,
358-
* and `tokenHash` is the computed TypeId/Token hash of the new UDT
359-
*
360-
* @example
361-
* ```typescript
362-
* const udt = new Udt(codeOutPoint, scriptConfig);
363-
* const { tx, tokenHash } = await udt.register(
364-
* signer,
365-
* { name: "My UDT", symbol: "MYT", decimals: 8, icon: "https://..." }
366-
* );
367-
* // Send tx.res or complete tx.res and send the transaction
368-
* ```
369-
*
370-
* @remarks
371-
* - Uses SSRI executor if available for advanced/SSRI-compliant registration.
372-
* - Falls back to legacy registration (TypeId pattern) if no executor is present.
373-
* - The token hash can be used as the args for the UDT type script.
374-
*/
375-
async register(
376-
signer: ccc.Signer,
377-
metadata: {
378-
name: string;
379-
symbol: string;
380-
decimals: number;
381-
icon: string;
382-
},
383-
tx?: ccc.TransactionLike | null,
384-
): Promise<{
385-
tx: ssri.ExecutorResponse<ccc.Transaction>;
386-
tokenHash: ccc.Hex;
387-
}> {
388-
const owner = await signer.getRecommendedAddressObj();
389-
const register = ccc.Transaction.from(tx ?? {});
390-
if (register.inputs.length === 0) {
391-
await register.completeInputsAtLeastOne(signer); // For `TypeId` calcuclation
392-
}
393-
const tokenHash = ccc.hashTypeId(
394-
register.inputs[0],
395-
register.outputs.length,
396-
);
397-
398-
let resTx;
399-
if (this.executor) {
400-
const res = await this.executor.runScriptTry(
401-
this.code,
402-
"UDTSSRI.create",
403-
[
404-
register.toBytes(),
405-
ccc.Script.from(owner.script).toBytes(),
406-
UdtMetadata.encode(metadata),
407-
],
408-
);
409-
if (res) {
410-
resTx = res.map((res) => ccc.Transaction.fromBytes(res));
411-
}
412-
}
413-
414-
// Fallback logic
415-
if (!resTx) {
416-
register.addOutput(
417-
{
418-
lock: owner.script,
419-
type: {
420-
codeHash:
421-
"00000000000000000000000000000000000000000000000000545950455f4944",
422-
hashType: "type",
423-
args: tokenHash,
424-
},
425-
},
426-
UdtMetadata.encode(metadata),
427-
);
428-
resTx = ssri.ExecutorResponse.new(register);
429-
}
430-
431-
return {
432-
tx: resTx.map((tx) => this.addCellDeps(tx)),
433-
tokenHash,
434-
};
435-
}
436-
437325
/**
438326
* Retrieves the human-readable name of the User Defined Token.
439327
* This method queries the UDT script to get the token's display name,
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
import { ccc } from "@ckb-ccc/core";
2+
import { ssri } from "@ckb-ccc/ssri";
3+
import { Udt, UdtConfigLike } from "../udt/index.js";
4+
5+
/**
6+
* The basic metadata of a UDT token.
7+
*
8+
* @example
9+
* ```typescript
10+
* const metadataMolecule = UdtMetadata.encode({
11+
* name: "My UDT",
12+
* symbol: "MYUDT",
13+
* decimals: 8,
14+
* icon: "https://example.com/icon.png",
15+
* });
16+
* ```
17+
*
18+
* @public
19+
* @category UDT
20+
*/
21+
export const UdtMetadata = ccc.mol.table({
22+
name: ccc.mol.String,
23+
symbol: ccc.mol.String,
24+
decimals: ccc.mol.Uint8,
25+
icon: ccc.mol.String,
26+
});
27+
28+
/**
29+
* Represents a UDT (User Defined Token) with separated SSRI metadata functionality.
30+
* @extends {Udt} This must be a SSRI UDT that does not fallback to xUDT.
31+
* @public
32+
*/
33+
export class UdtRegister extends Udt {
34+
constructor(
35+
code: ccc.OutPointLike,
36+
script: ccc.ScriptLike,
37+
config: UdtConfigLike & { executor: ssri.Executor },
38+
) {
39+
super(code, script, config);
40+
}
41+
42+
/**
43+
* Registers (creates) a new UDT with on-chain metadata.
44+
* This method creates a new unique UDT instance (usually with a TypeId pattern),
45+
* assigns on-chain metadata (name, symbol, decimals, icon), and returns a transaction
46+
* to instantiate the new token. Often used by the deployer/owner.
47+
*
48+
* @param signer - The signer (owner) who will initialize and own the new UDT
49+
* @param metadata - Object containing UDT metadata (name, symbol, decimals, icon)
50+
* @param tx - Optional existing transaction to build upon
51+
* @returns Promise resolving to `{ tx, tokenHash }`, where `tx` is the deployment transaction,
52+
* and `tokenHash` is the computed TypeId/Token hash of the new UDT
53+
*
54+
* @example
55+
* ```typescript
56+
* const udt = new Udt(codeOutPoint, scriptConfig);
57+
* const { tx, tokenHash } = await udt.register(
58+
* signer,
59+
* { name: "My UDT", symbol: "MYT", decimals: 8, icon: "https://..." }
60+
* );
61+
* // Send tx.res or complete tx.res and send the transaction
62+
* ```
63+
*
64+
* @remarks
65+
* - Uses SSRI executor if available for advanced/SSRI-compliant registration.
66+
* - Falls back to legacy registration (TypeId pattern) if no executor is present.
67+
* - The token hash can be used as the args for the UDT type script.
68+
*/
69+
async register(
70+
signer: ccc.Signer,
71+
metadata: {
72+
name: string;
73+
symbol: string;
74+
decimals: number;
75+
icon: string;
76+
},
77+
tx?: ccc.TransactionLike | null,
78+
): Promise<{
79+
tx: ssri.ExecutorResponse<ccc.Transaction>;
80+
tokenHash: ccc.Hex;
81+
}> {
82+
const owner = await signer.getRecommendedAddressObj();
83+
const register = ccc.Transaction.from(tx ?? {});
84+
if (register.inputs.length === 0) {
85+
await register.completeInputsAtLeastOne(signer); // For `TypeId` calcuclation
86+
}
87+
const tokenHash = ccc.hashTypeId(
88+
register.inputs[0],
89+
register.outputs.length,
90+
);
91+
92+
let resTx;
93+
if (this.executor) {
94+
const res = await this.executor.runScriptTry(
95+
this.code,
96+
"UDTSSRI.create",
97+
[
98+
register.toBytes(),
99+
ccc.Script.from(owner.script).toBytes(),
100+
UdtMetadata.encode(metadata),
101+
],
102+
);
103+
if (res) {
104+
resTx = res.map((res) => ccc.Transaction.fromBytes(res));
105+
}
106+
}
107+
108+
// Fallback logic
109+
if (!resTx) {
110+
register.addOutput(
111+
{
112+
lock: owner.script,
113+
type: {
114+
codeHash:
115+
"00000000000000000000000000000000000000000000000000545950455f4944",
116+
hashType: "type",
117+
args: tokenHash,
118+
},
119+
},
120+
UdtMetadata.encode(metadata),
121+
);
122+
resTx = ssri.ExecutorResponse.new(register);
123+
}
124+
125+
return {
126+
tx: resTx.map((tx) => this.addCellDeps(tx)),
127+
tokenHash,
128+
};
129+
}
130+
}

0 commit comments

Comments
 (0)