tusdt-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +167 -0
- package/dist/chunk-5HS7VSOA.js +1844 -0
- package/dist/chunk-5HS7VSOA.js.map +1 -0
- package/dist/client.d.ts +2 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +3 -0
- package/dist/client.js.map +1 -0
- package/dist/contract/events.d.ts +39 -0
- package/dist/contract/events.d.ts.map +1 -0
- package/dist/contract/finalized-events.d.ts +32 -0
- package/dist/contract/finalized-events.d.ts.map +1 -0
- package/dist/contract/helpers.d.ts +19 -0
- package/dist/contract/helpers.d.ts.map +1 -0
- package/dist/contract/payment-listener.d.ts +88 -0
- package/dist/contract/payment-listener.d.ts.map +1 -0
- package/dist/contract/queries.d.ts +23 -0
- package/dist/contract/queries.d.ts.map +1 -0
- package/dist/contract/transactions.d.ts +36 -0
- package/dist/contract/transactions.d.ts.map +1 -0
- package/dist/contract/tusdt-contract.d.ts +186 -0
- package/dist/contract/tusdt-contract.d.ts.map +1 -0
- package/dist/core/constants.d.ts +10 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/errors.d.ts +85 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/types.d.ts +97 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/validation.d.ts +30 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +19 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +204 -0
- package/dist/server.js.map +1 -0
- package/dist/signer/types.d.ts +2 -0
- package/dist/signer/types.d.ts.map +1 -0
- package/metadata/tusdt_erc20.json +1133 -0
- package/package.json +83 -0
|
@@ -0,0 +1,1844 @@
|
|
|
1
|
+
import { Contract } from 'dedot/contracts';
|
|
2
|
+
|
|
3
|
+
// src/contract/tusdt-contract.ts
|
|
4
|
+
|
|
5
|
+
// src/core/constants.ts
|
|
6
|
+
var U64_MAX = 18446744073709551615n;
|
|
7
|
+
var ZERO_BALANCE = 0n;
|
|
8
|
+
var ZERO_ADDRESS = "0x" + "00".repeat(32);
|
|
9
|
+
|
|
10
|
+
// src/core/errors.ts
|
|
11
|
+
var TusdtSdkError = class extends Error {
|
|
12
|
+
constructor(message, options) {
|
|
13
|
+
super(message, options);
|
|
14
|
+
this.name = "TusdtSdkError";
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
var ValidationError = class extends TusdtSdkError {
|
|
18
|
+
constructor(message) {
|
|
19
|
+
super(message);
|
|
20
|
+
this.name = "ValidationError";
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
var ContractError = class extends TusdtSdkError {
|
|
24
|
+
contractErrorType;
|
|
25
|
+
constructor(message, contractErrorType) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "ContractError";
|
|
28
|
+
this.contractErrorType = contractErrorType;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
var InsufficientBalanceError = class extends ContractError {
|
|
32
|
+
constructor(message) {
|
|
33
|
+
super(
|
|
34
|
+
message ?? "Insufficient token balance for this operation",
|
|
35
|
+
"InsufficientBalance"
|
|
36
|
+
);
|
|
37
|
+
this.name = "InsufficientBalanceError";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var InsufficientAllowanceError = class extends ContractError {
|
|
41
|
+
constructor(message) {
|
|
42
|
+
super(
|
|
43
|
+
message ?? "Insufficient allowance for this transfer",
|
|
44
|
+
"InsufficientAllowance"
|
|
45
|
+
);
|
|
46
|
+
this.name = "InsufficientAllowanceError";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
var NotControllerError = class extends ContractError {
|
|
50
|
+
constructor(message) {
|
|
51
|
+
super(
|
|
52
|
+
message ?? "Only the controller can perform this operation",
|
|
53
|
+
"NotController"
|
|
54
|
+
);
|
|
55
|
+
this.name = "NotControllerError";
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var DryRunError = class extends TusdtSdkError {
|
|
59
|
+
dispatchError;
|
|
60
|
+
constructor(message, dispatchError) {
|
|
61
|
+
super(message);
|
|
62
|
+
this.name = "DryRunError";
|
|
63
|
+
this.dispatchError = dispatchError;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var DispatchError = class extends TusdtSdkError {
|
|
67
|
+
dispatchError;
|
|
68
|
+
constructor(message, dispatchError) {
|
|
69
|
+
super(message);
|
|
70
|
+
this.name = "DispatchError";
|
|
71
|
+
this.dispatchError = dispatchError;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
var ConnectionError = class extends TusdtSdkError {
|
|
75
|
+
constructor(message) {
|
|
76
|
+
super(message);
|
|
77
|
+
this.name = "ConnectionError";
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var TimeoutError = class extends TusdtSdkError {
|
|
81
|
+
constructor(message) {
|
|
82
|
+
super(message);
|
|
83
|
+
this.name = "TimeoutError";
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
function mapContractError(error) {
|
|
87
|
+
if (typeof error === "string") {
|
|
88
|
+
switch (error) {
|
|
89
|
+
case "InsufficientBalance":
|
|
90
|
+
return new InsufficientBalanceError();
|
|
91
|
+
case "InsufficientAllowance":
|
|
92
|
+
return new InsufficientAllowanceError();
|
|
93
|
+
case "NotController":
|
|
94
|
+
return new NotControllerError();
|
|
95
|
+
}
|
|
96
|
+
if (error.includes("InsufficientBalance"))
|
|
97
|
+
return new InsufficientBalanceError();
|
|
98
|
+
if (error.includes("InsufficientAllowance"))
|
|
99
|
+
return new InsufficientAllowanceError();
|
|
100
|
+
if (error.includes("NotController")) return new NotControllerError();
|
|
101
|
+
}
|
|
102
|
+
if (error && typeof error === "object" && "type" in error) {
|
|
103
|
+
const variant = error.type;
|
|
104
|
+
switch (variant) {
|
|
105
|
+
case "InsufficientBalance":
|
|
106
|
+
return new InsufficientBalanceError();
|
|
107
|
+
case "InsufficientAllowance":
|
|
108
|
+
return new InsufficientAllowanceError();
|
|
109
|
+
case "NotController":
|
|
110
|
+
return new NotControllerError();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return new ContractError(
|
|
114
|
+
`Contract rejected the call: ${JSON.stringify(error)}`,
|
|
115
|
+
"Unknown"
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// src/core/validation.ts
|
|
120
|
+
function validateBalance(value) {
|
|
121
|
+
if (typeof value !== "bigint") {
|
|
122
|
+
throw new ValidationError(
|
|
123
|
+
`Balance must be a bigint, received ${typeof value}`
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
if (value < 0n) {
|
|
127
|
+
throw new ValidationError("Balance cannot be negative");
|
|
128
|
+
}
|
|
129
|
+
if (value > U64_MAX) {
|
|
130
|
+
throw new ValidationError(
|
|
131
|
+
`Balance ${value} exceeds u64 maximum (${U64_MAX})`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function validateAddress(address) {
|
|
136
|
+
if (typeof address !== "string" || address.length === 0) {
|
|
137
|
+
throw new ValidationError("Address must be a non-empty string");
|
|
138
|
+
}
|
|
139
|
+
if (address.startsWith("0x")) {
|
|
140
|
+
if (address.length !== 66) {
|
|
141
|
+
throw new ValidationError(
|
|
142
|
+
`Invalid hex address length: expected 66 characters, got ${address.length}`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function validateOverflowSafe(recipientBalance, transferAmount) {
|
|
148
|
+
if (recipientBalance + transferAmount > U64_MAX) {
|
|
149
|
+
throw new ValidationError(
|
|
150
|
+
`Transfer would overflow recipient balance: ${recipientBalance} + ${transferAmount} > u64 max (${U64_MAX})`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function isKeyringPair(signer) {
|
|
155
|
+
return typeof signer === "object" && signer !== null && "address" in signer && "sign" in signer && typeof signer.sign === "function";
|
|
156
|
+
}
|
|
157
|
+
function getSignerAddress(signer) {
|
|
158
|
+
return signer.address;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/contract/queries.ts
|
|
162
|
+
function accountIdToString(accountId) {
|
|
163
|
+
if (typeof accountId === "string") return accountId;
|
|
164
|
+
if (accountId && typeof accountId === "object") {
|
|
165
|
+
if ("address" in accountId && typeof accountId.address === "function") {
|
|
166
|
+
return accountId.address();
|
|
167
|
+
}
|
|
168
|
+
if ("toString" in accountId) {
|
|
169
|
+
return accountId.toString();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return String(accountId);
|
|
173
|
+
}
|
|
174
|
+
async function queryController(contract) {
|
|
175
|
+
try {
|
|
176
|
+
const result = await contract.query.controller();
|
|
177
|
+
return accountIdToString(result.data);
|
|
178
|
+
} catch (error) {
|
|
179
|
+
throw new DryRunError(
|
|
180
|
+
`Failed to query controller: ${error instanceof Error ? error.message : String(error)}`,
|
|
181
|
+
error
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
async function queryTotalSupply(contract) {
|
|
186
|
+
try {
|
|
187
|
+
const result = await contract.query.totalSupply();
|
|
188
|
+
return BigInt(result.data);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throw new DryRunError(
|
|
191
|
+
`Failed to query total_supply: ${error instanceof Error ? error.message : String(error)}`,
|
|
192
|
+
error
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function queryBalanceOf(contract, owner) {
|
|
197
|
+
validateAddress(owner);
|
|
198
|
+
try {
|
|
199
|
+
const result = await contract.query.balanceOf(owner);
|
|
200
|
+
return BigInt(result.data);
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw new DryRunError(
|
|
203
|
+
`Failed to query balance_of: ${error instanceof Error ? error.message : String(error)}`,
|
|
204
|
+
error
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async function queryAllowance(contract, owner, spender) {
|
|
209
|
+
validateAddress(owner);
|
|
210
|
+
validateAddress(spender);
|
|
211
|
+
try {
|
|
212
|
+
const result = await contract.query.allowance(owner, spender);
|
|
213
|
+
return BigInt(result.data);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
throw new DryRunError(
|
|
216
|
+
`Failed to query allowance: ${error instanceof Error ? error.message : String(error)}`,
|
|
217
|
+
error
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function createDryRunContract(contract, callerAddress) {
|
|
222
|
+
const innerContract = contract;
|
|
223
|
+
return new Contract(
|
|
224
|
+
innerContract.client,
|
|
225
|
+
innerContract.metadata,
|
|
226
|
+
innerContract.address,
|
|
227
|
+
{ defaultCaller: callerAddress }
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
async function signAndWait(txCall, signer, options) {
|
|
231
|
+
const waitFor = options?.waitFor ?? "bestChainBlockIncluded";
|
|
232
|
+
try {
|
|
233
|
+
let pendingTx;
|
|
234
|
+
if (isKeyringPair(signer)) {
|
|
235
|
+
pendingTx = txCall.signAndSend(signer);
|
|
236
|
+
} else {
|
|
237
|
+
pendingTx = txCall.signAndSend(signer.address, { signer: signer.signer });
|
|
238
|
+
}
|
|
239
|
+
let result;
|
|
240
|
+
if (waitFor === "finalized") {
|
|
241
|
+
result = await pendingTx.untilFinalized();
|
|
242
|
+
} else {
|
|
243
|
+
result = await pendingTx.untilBestChainBlockIncluded();
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
events: result.events ?? [],
|
|
247
|
+
// Dedot's TxStatus is a discriminated union:
|
|
248
|
+
// { type: 'BestChainBlockIncluded', value: { blockHash, blockNumber, txIndex } }
|
|
249
|
+
// { type: 'Finalized', value: { blockHash, blockNumber, txIndex } }
|
|
250
|
+
blockHash: result.status?.value?.blockHash?.toString() ?? "",
|
|
251
|
+
txHash: result.txHash?.toString() ?? ""
|
|
252
|
+
};
|
|
253
|
+
} catch (error) {
|
|
254
|
+
if (error && typeof error === "object") {
|
|
255
|
+
const errorObj = error;
|
|
256
|
+
if (errorObj.dispatchError) {
|
|
257
|
+
throw new DispatchError(
|
|
258
|
+
`Transaction dispatch failed: ${String(error)}`,
|
|
259
|
+
errorObj.dispatchError
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
throw error;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function extractGasEstimate(rawResult) {
|
|
267
|
+
const gasRequired = rawResult?.gasRequired;
|
|
268
|
+
return {
|
|
269
|
+
refTime: BigInt(gasRequired?.refTime?.toString() ?? "0"),
|
|
270
|
+
proofSize: BigInt(gasRequired?.proofSize?.toString() ?? "0")
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
function decodeTransferEvents(contract, events, blockHash) {
|
|
274
|
+
try {
|
|
275
|
+
const transferEvents = contract.events.Transfer.filter(events);
|
|
276
|
+
return transferEvents.map((evt) => {
|
|
277
|
+
const data = evt.data ?? evt;
|
|
278
|
+
return {
|
|
279
|
+
from: data.from?.toString() ?? null,
|
|
280
|
+
to: data.to?.toString() ?? null,
|
|
281
|
+
value: BigInt(data.value ?? 0),
|
|
282
|
+
blockHash
|
|
283
|
+
};
|
|
284
|
+
});
|
|
285
|
+
} catch {
|
|
286
|
+
return [];
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function decodeApprovalEvents(contract, events, blockHash) {
|
|
290
|
+
try {
|
|
291
|
+
const approvalEvents = contract.events.Approval.filter(events);
|
|
292
|
+
return approvalEvents.map((evt) => {
|
|
293
|
+
const data = evt.data ?? evt;
|
|
294
|
+
return {
|
|
295
|
+
owner: data.owner?.toString() ?? "",
|
|
296
|
+
spender: data.spender?.toString() ?? "",
|
|
297
|
+
value: BigInt(data.value ?? 0),
|
|
298
|
+
blockHash
|
|
299
|
+
};
|
|
300
|
+
});
|
|
301
|
+
} catch {
|
|
302
|
+
return [];
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async function dryRunMutation(contract, signerAddress, message, args) {
|
|
306
|
+
const dryRunContract = createDryRunContract(contract, signerAddress);
|
|
307
|
+
const queryFn = dryRunContract.query[message];
|
|
308
|
+
if (!queryFn) {
|
|
309
|
+
throw new DryRunError(`Unknown contract message: ${message}`);
|
|
310
|
+
}
|
|
311
|
+
let result;
|
|
312
|
+
try {
|
|
313
|
+
result = await queryFn(...args);
|
|
314
|
+
} catch (error) {
|
|
315
|
+
throw new DryRunError(
|
|
316
|
+
`Dry-run failed for ${message}: ${error instanceof Error ? error.message : String(error)}`,
|
|
317
|
+
error
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
const data = result.data;
|
|
321
|
+
if (data && typeof data === "object" && "isErr" in data && data.isErr) {
|
|
322
|
+
throw mapContractError(data.err);
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
gasEstimate: extractGasEstimate(result.raw),
|
|
326
|
+
raw: result.raw
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
async function executeTransfer(contract, signer, to, value, options) {
|
|
330
|
+
const signerAddress = getSignerAddress(signer);
|
|
331
|
+
validateAddress(to);
|
|
332
|
+
validateBalance(value);
|
|
333
|
+
if (value > 0n && signerAddress !== to) {
|
|
334
|
+
const recipientBalance = await queryBalanceOf(contract, to);
|
|
335
|
+
validateOverflowSafe(recipientBalance, value);
|
|
336
|
+
}
|
|
337
|
+
const { gasEstimate, raw } = await dryRunMutation(
|
|
338
|
+
contract,
|
|
339
|
+
signerAddress,
|
|
340
|
+
"transfer",
|
|
341
|
+
[to, value]
|
|
342
|
+
);
|
|
343
|
+
const txCall = contract.tx.transfer(to, value, {
|
|
344
|
+
gasLimit: raw.gasRequired
|
|
345
|
+
});
|
|
346
|
+
const { events, blockHash, txHash } = await signAndWait(txCall, signer, options);
|
|
347
|
+
const transfers = decodeTransferEvents(contract, events, blockHash);
|
|
348
|
+
const approvals = decodeApprovalEvents(contract, events, blockHash);
|
|
349
|
+
return { blockHash, txHash, gasEstimate, transfers, approvals };
|
|
350
|
+
}
|
|
351
|
+
async function executeApprove(contract, signer, spender, value, options) {
|
|
352
|
+
const signerAddress = getSignerAddress(signer);
|
|
353
|
+
validateAddress(spender);
|
|
354
|
+
validateBalance(value);
|
|
355
|
+
const { gasEstimate, raw } = await dryRunMutation(
|
|
356
|
+
contract,
|
|
357
|
+
signerAddress,
|
|
358
|
+
"approve",
|
|
359
|
+
[spender, value]
|
|
360
|
+
);
|
|
361
|
+
const txCall = contract.tx.approve(spender, value, {
|
|
362
|
+
gasLimit: raw.gasRequired
|
|
363
|
+
});
|
|
364
|
+
const { events, blockHash, txHash } = await signAndWait(txCall, signer, options);
|
|
365
|
+
const transfers = decodeTransferEvents(contract, events, blockHash);
|
|
366
|
+
const approvals = decodeApprovalEvents(contract, events, blockHash);
|
|
367
|
+
return { blockHash, txHash, gasEstimate, transfers, approvals };
|
|
368
|
+
}
|
|
369
|
+
async function executeTransferFrom(contract, signer, from, to, value, options) {
|
|
370
|
+
const signerAddress = getSignerAddress(signer);
|
|
371
|
+
validateAddress(from);
|
|
372
|
+
validateAddress(to);
|
|
373
|
+
validateBalance(value);
|
|
374
|
+
if (value > 0n && from !== to) {
|
|
375
|
+
const recipientBalance = await queryBalanceOf(contract, to);
|
|
376
|
+
validateOverflowSafe(recipientBalance, value);
|
|
377
|
+
}
|
|
378
|
+
const { gasEstimate, raw } = await dryRunMutation(
|
|
379
|
+
contract,
|
|
380
|
+
signerAddress,
|
|
381
|
+
"transferFrom",
|
|
382
|
+
[from, to, value]
|
|
383
|
+
);
|
|
384
|
+
const txCall = contract.tx.transferFrom(from, to, value, {
|
|
385
|
+
gasLimit: raw.gasRequired
|
|
386
|
+
});
|
|
387
|
+
const { events, blockHash, txHash } = await signAndWait(txCall, signer, options);
|
|
388
|
+
const transfers = decodeTransferEvents(contract, events, blockHash);
|
|
389
|
+
const approvals = decodeApprovalEvents(contract, events, blockHash);
|
|
390
|
+
return { blockHash, txHash, gasEstimate, transfers, approvals };
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// src/contract/events.ts
|
|
394
|
+
async function subscribeTransfer(client, contract, callback, options) {
|
|
395
|
+
const unsub = await client.rpc.chain_subscribeNewHeads(async (header) => {
|
|
396
|
+
try {
|
|
397
|
+
const blockHash = header.hash?.toString() ?? header.parentHash?.toString() ?? "";
|
|
398
|
+
const events = await client.query.system.events.at(blockHash);
|
|
399
|
+
const transferEvents = contract.events.Transfer.filter(events);
|
|
400
|
+
for (const evt of transferEvents) {
|
|
401
|
+
const data = evt.data ?? evt;
|
|
402
|
+
callback({
|
|
403
|
+
from: data.from?.toString() ?? null,
|
|
404
|
+
to: data.to?.toString() ?? null,
|
|
405
|
+
value: BigInt(data.value ?? 0),
|
|
406
|
+
blockHash
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
} catch (error) {
|
|
410
|
+
if (options?.onError) {
|
|
411
|
+
options.onError(error instanceof Error ? error : new Error(String(error)));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
return typeof unsub === "function" ? unsub : () => {
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
async function subscribeApproval(client, contract, callback, options) {
|
|
419
|
+
const unsub = await client.rpc.chain_subscribeNewHeads(async (header) => {
|
|
420
|
+
try {
|
|
421
|
+
const blockHash = header.hash?.toString() ?? header.parentHash?.toString() ?? "";
|
|
422
|
+
const events = await client.query.system.events.at(blockHash);
|
|
423
|
+
const approvalEvents = contract.events.Approval.filter(events);
|
|
424
|
+
for (const evt of approvalEvents) {
|
|
425
|
+
const data = evt.data ?? evt;
|
|
426
|
+
callback({
|
|
427
|
+
owner: data.owner?.toString() ?? "",
|
|
428
|
+
spender: data.spender?.toString() ?? "",
|
|
429
|
+
value: BigInt(data.value ?? 0),
|
|
430
|
+
blockHash
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
} catch (error) {
|
|
434
|
+
if (options?.onError) {
|
|
435
|
+
options.onError(error instanceof Error ? error : new Error(String(error)));
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
});
|
|
439
|
+
return typeof unsub === "function" ? unsub : () => {
|
|
440
|
+
};
|
|
441
|
+
}
|
|
442
|
+
async function subscribeTransferFrom(client, contract, account, callback, options) {
|
|
443
|
+
return subscribeTransfer(client, contract, (event) => {
|
|
444
|
+
if (event.from === account) {
|
|
445
|
+
callback(event);
|
|
446
|
+
}
|
|
447
|
+
}, options);
|
|
448
|
+
}
|
|
449
|
+
async function subscribeTransferTo(client, contract, account, callback, options) {
|
|
450
|
+
return subscribeTransfer(client, contract, (event) => {
|
|
451
|
+
if (event.to === account) {
|
|
452
|
+
callback(event);
|
|
453
|
+
}
|
|
454
|
+
}, options);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// src/contract/finalized-events.ts
|
|
458
|
+
function parseBlockNumber(raw) {
|
|
459
|
+
if (typeof raw === "number") return raw;
|
|
460
|
+
return Number(String(raw ?? 0));
|
|
461
|
+
}
|
|
462
|
+
async function watchFinalizedTransfers(client, contract, callback, options) {
|
|
463
|
+
const unsub = await client.rpc.chain_subscribeFinalizedHeads(
|
|
464
|
+
async (header) => {
|
|
465
|
+
try {
|
|
466
|
+
const blockHash = header.hash?.toString() ?? header.parentHash?.toString() ?? "";
|
|
467
|
+
const blockNumber = parseBlockNumber(header.number);
|
|
468
|
+
const events = await client.query.system.events.at(blockHash);
|
|
469
|
+
const transferEvents = contract.events.Transfer.filter(events);
|
|
470
|
+
for (let i = 0; i < transferEvents.length; i++) {
|
|
471
|
+
const evt = transferEvents[i];
|
|
472
|
+
const data = evt.data ?? evt;
|
|
473
|
+
callback({
|
|
474
|
+
from: data.from?.toString() ?? null,
|
|
475
|
+
to: data.to?.toString() ?? null,
|
|
476
|
+
value: BigInt(data.value ?? 0),
|
|
477
|
+
blockHash,
|
|
478
|
+
blockNumber,
|
|
479
|
+
txIndex: i
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
} catch (error) {
|
|
483
|
+
if (options?.onError) {
|
|
484
|
+
options.onError(
|
|
485
|
+
error instanceof Error ? error : new Error(String(error))
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
);
|
|
491
|
+
return typeof unsub === "function" ? unsub : () => {
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
async function watchFinalizedTransfersTo(client, contract, account, callback, options) {
|
|
495
|
+
return watchFinalizedTransfers(
|
|
496
|
+
client,
|
|
497
|
+
contract,
|
|
498
|
+
(event) => {
|
|
499
|
+
if (event.to === account) callback(event);
|
|
500
|
+
},
|
|
501
|
+
options
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
// src/contract/helpers.ts
|
|
506
|
+
async function safeApprove(contract, signer, spender, newValue, options) {
|
|
507
|
+
const signerAddress = getSignerAddress(signer);
|
|
508
|
+
const currentAllowance = await queryAllowance(
|
|
509
|
+
contract,
|
|
510
|
+
signerAddress,
|
|
511
|
+
spender
|
|
512
|
+
);
|
|
513
|
+
if (currentAllowance > ZERO_BALANCE && newValue > ZERO_BALANCE) {
|
|
514
|
+
await executeApprove(contract, signer, spender, ZERO_BALANCE, options);
|
|
515
|
+
}
|
|
516
|
+
return executeApprove(contract, signer, spender, newValue, options);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// metadata/tusdt_erc20.json
|
|
520
|
+
var tusdt_erc20_default = {
|
|
521
|
+
source: {
|
|
522
|
+
hash: "0x5ad2ab290b4330dc0f70638c4f3d639b15e0c54808109021bb9dc80d0b914dbf",
|
|
523
|
+
language: "ink! 5.1.1",
|
|
524
|
+
compiler: "rustc 1.93.0",
|
|
525
|
+
build_info: {
|
|
526
|
+
build_mode: "Debug",
|
|
527
|
+
cargo_contract_version: "5.0.3",
|
|
528
|
+
rust_toolchain: "stable-x86_64-unknown-linux-gnu",
|
|
529
|
+
wasm_opt_settings: {
|
|
530
|
+
keep_debug_symbols: false,
|
|
531
|
+
optimization_passes: "Z"
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
contract: {
|
|
536
|
+
name: "tusdt-erc20",
|
|
537
|
+
version: "0.1.0",
|
|
538
|
+
authors: [
|
|
539
|
+
"tensorusd admin@tensorusd.com"
|
|
540
|
+
]
|
|
541
|
+
},
|
|
542
|
+
image: null,
|
|
543
|
+
spec: {
|
|
544
|
+
constructors: [
|
|
545
|
+
{
|
|
546
|
+
args: [
|
|
547
|
+
{
|
|
548
|
+
label: "controller",
|
|
549
|
+
type: {
|
|
550
|
+
displayName: [
|
|
551
|
+
"AccountId"
|
|
552
|
+
],
|
|
553
|
+
type: 0
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
],
|
|
557
|
+
default: false,
|
|
558
|
+
docs: [
|
|
559
|
+
"Initializes the token contract with the specified controller account."
|
|
560
|
+
],
|
|
561
|
+
label: "new",
|
|
562
|
+
payable: false,
|
|
563
|
+
returnType: {
|
|
564
|
+
displayName: [
|
|
565
|
+
"ink_primitives",
|
|
566
|
+
"ConstructorResult"
|
|
567
|
+
],
|
|
568
|
+
type: 14
|
|
569
|
+
},
|
|
570
|
+
selector: "0x9bae9d5e"
|
|
571
|
+
}
|
|
572
|
+
],
|
|
573
|
+
docs: [],
|
|
574
|
+
environment: {
|
|
575
|
+
accountId: {
|
|
576
|
+
displayName: [
|
|
577
|
+
"AccountId"
|
|
578
|
+
],
|
|
579
|
+
type: 0
|
|
580
|
+
},
|
|
581
|
+
balance: {
|
|
582
|
+
displayName: [
|
|
583
|
+
"Balance"
|
|
584
|
+
],
|
|
585
|
+
type: 3
|
|
586
|
+
},
|
|
587
|
+
blockNumber: {
|
|
588
|
+
displayName: [
|
|
589
|
+
"BlockNumber"
|
|
590
|
+
],
|
|
591
|
+
type: 23
|
|
592
|
+
},
|
|
593
|
+
chainExtension: {
|
|
594
|
+
displayName: [
|
|
595
|
+
"ChainExtension"
|
|
596
|
+
],
|
|
597
|
+
type: 24
|
|
598
|
+
},
|
|
599
|
+
hash: {
|
|
600
|
+
displayName: [
|
|
601
|
+
"Hash"
|
|
602
|
+
],
|
|
603
|
+
type: 22
|
|
604
|
+
},
|
|
605
|
+
maxEventTopics: 4,
|
|
606
|
+
staticBufferSize: 16384,
|
|
607
|
+
timestamp: {
|
|
608
|
+
displayName: [
|
|
609
|
+
"Timestamp"
|
|
610
|
+
],
|
|
611
|
+
type: 3
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
events: [
|
|
615
|
+
{
|
|
616
|
+
args: [
|
|
617
|
+
{
|
|
618
|
+
docs: [],
|
|
619
|
+
indexed: true,
|
|
620
|
+
label: "owner",
|
|
621
|
+
type: {
|
|
622
|
+
displayName: [
|
|
623
|
+
"AccountId"
|
|
624
|
+
],
|
|
625
|
+
type: 0
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
docs: [],
|
|
630
|
+
indexed: true,
|
|
631
|
+
label: "spender",
|
|
632
|
+
type: {
|
|
633
|
+
displayName: [
|
|
634
|
+
"AccountId"
|
|
635
|
+
],
|
|
636
|
+
type: 0
|
|
637
|
+
}
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
docs: [],
|
|
641
|
+
indexed: false,
|
|
642
|
+
label: "value",
|
|
643
|
+
type: {
|
|
644
|
+
displayName: [
|
|
645
|
+
"Balance"
|
|
646
|
+
],
|
|
647
|
+
type: 3
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
],
|
|
651
|
+
docs: [],
|
|
652
|
+
label: "Approval",
|
|
653
|
+
module_path: "tusdt_erc20::tusdt",
|
|
654
|
+
signature_topic: "0x1a35e726f5feffda199144f6097b2ba23713e549bfcbe090c0981e3bcdfbcc1d"
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
args: [
|
|
658
|
+
{
|
|
659
|
+
docs: [],
|
|
660
|
+
indexed: true,
|
|
661
|
+
label: "from",
|
|
662
|
+
type: {
|
|
663
|
+
displayName: [
|
|
664
|
+
"Option"
|
|
665
|
+
],
|
|
666
|
+
type: 21
|
|
667
|
+
}
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
docs: [],
|
|
671
|
+
indexed: true,
|
|
672
|
+
label: "to",
|
|
673
|
+
type: {
|
|
674
|
+
displayName: [
|
|
675
|
+
"Option"
|
|
676
|
+
],
|
|
677
|
+
type: 21
|
|
678
|
+
}
|
|
679
|
+
},
|
|
680
|
+
{
|
|
681
|
+
docs: [],
|
|
682
|
+
indexed: false,
|
|
683
|
+
label: "value",
|
|
684
|
+
type: {
|
|
685
|
+
displayName: [
|
|
686
|
+
"Balance"
|
|
687
|
+
],
|
|
688
|
+
type: 3
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
],
|
|
692
|
+
docs: [],
|
|
693
|
+
label: "Transfer",
|
|
694
|
+
module_path: "tusdt_erc20::tusdt",
|
|
695
|
+
signature_topic: "0xb5b61a3e6a21a16be4f044b517c28ac692492f73c5bfd3f60178ad98c767f4cb"
|
|
696
|
+
}
|
|
697
|
+
],
|
|
698
|
+
lang_error: {
|
|
699
|
+
displayName: [
|
|
700
|
+
"ink",
|
|
701
|
+
"LangError"
|
|
702
|
+
],
|
|
703
|
+
type: 15
|
|
704
|
+
},
|
|
705
|
+
messages: [
|
|
706
|
+
{
|
|
707
|
+
args: [],
|
|
708
|
+
default: false,
|
|
709
|
+
docs: [
|
|
710
|
+
" Returns the controller account ID."
|
|
711
|
+
],
|
|
712
|
+
label: "controller",
|
|
713
|
+
mutates: false,
|
|
714
|
+
payable: false,
|
|
715
|
+
returnType: {
|
|
716
|
+
displayName: [
|
|
717
|
+
"ink",
|
|
718
|
+
"MessageResult"
|
|
719
|
+
],
|
|
720
|
+
type: 16
|
|
721
|
+
},
|
|
722
|
+
selector: "0x7b3bfba9"
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
args: [],
|
|
726
|
+
default: false,
|
|
727
|
+
docs: [
|
|
728
|
+
" Returns the total supply of tokens in circulation."
|
|
729
|
+
],
|
|
730
|
+
label: "total_supply",
|
|
731
|
+
mutates: false,
|
|
732
|
+
payable: false,
|
|
733
|
+
returnType: {
|
|
734
|
+
displayName: [
|
|
735
|
+
"ink",
|
|
736
|
+
"MessageResult"
|
|
737
|
+
],
|
|
738
|
+
type: 17
|
|
739
|
+
},
|
|
740
|
+
selector: "0xdb6375a8"
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
args: [
|
|
744
|
+
{
|
|
745
|
+
label: "owner",
|
|
746
|
+
type: {
|
|
747
|
+
displayName: [
|
|
748
|
+
"AccountId"
|
|
749
|
+
],
|
|
750
|
+
type: 0
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
],
|
|
754
|
+
default: false,
|
|
755
|
+
docs: [
|
|
756
|
+
" Returns the token balance of an account."
|
|
757
|
+
],
|
|
758
|
+
label: "balance_of",
|
|
759
|
+
mutates: false,
|
|
760
|
+
payable: false,
|
|
761
|
+
returnType: {
|
|
762
|
+
displayName: [
|
|
763
|
+
"ink",
|
|
764
|
+
"MessageResult"
|
|
765
|
+
],
|
|
766
|
+
type: 17
|
|
767
|
+
},
|
|
768
|
+
selector: "0x0f755a56"
|
|
769
|
+
},
|
|
770
|
+
{
|
|
771
|
+
args: [
|
|
772
|
+
{
|
|
773
|
+
label: "owner",
|
|
774
|
+
type: {
|
|
775
|
+
displayName: [
|
|
776
|
+
"AccountId"
|
|
777
|
+
],
|
|
778
|
+
type: 0
|
|
779
|
+
}
|
|
780
|
+
},
|
|
781
|
+
{
|
|
782
|
+
label: "spender",
|
|
783
|
+
type: {
|
|
784
|
+
displayName: [
|
|
785
|
+
"AccountId"
|
|
786
|
+
],
|
|
787
|
+
type: 0
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
],
|
|
791
|
+
default: false,
|
|
792
|
+
docs: [
|
|
793
|
+
" Returns the amount of tokens that a spender is allowed to transfer from an owner's account."
|
|
794
|
+
],
|
|
795
|
+
label: "allowance",
|
|
796
|
+
mutates: false,
|
|
797
|
+
payable: false,
|
|
798
|
+
returnType: {
|
|
799
|
+
displayName: [
|
|
800
|
+
"ink",
|
|
801
|
+
"MessageResult"
|
|
802
|
+
],
|
|
803
|
+
type: 17
|
|
804
|
+
},
|
|
805
|
+
selector: "0x6a00165e"
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
args: [
|
|
809
|
+
{
|
|
810
|
+
label: "to",
|
|
811
|
+
type: {
|
|
812
|
+
displayName: [
|
|
813
|
+
"AccountId"
|
|
814
|
+
],
|
|
815
|
+
type: 0
|
|
816
|
+
}
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
label: "value",
|
|
820
|
+
type: {
|
|
821
|
+
displayName: [
|
|
822
|
+
"Balance"
|
|
823
|
+
],
|
|
824
|
+
type: 3
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
],
|
|
828
|
+
default: false,
|
|
829
|
+
docs: [
|
|
830
|
+
" Transfers tokens from the caller to a recipient account."
|
|
831
|
+
],
|
|
832
|
+
label: "transfer",
|
|
833
|
+
mutates: true,
|
|
834
|
+
payable: false,
|
|
835
|
+
returnType: {
|
|
836
|
+
displayName: [
|
|
837
|
+
"ink",
|
|
838
|
+
"MessageResult"
|
|
839
|
+
],
|
|
840
|
+
type: 18
|
|
841
|
+
},
|
|
842
|
+
selector: "0x84a15da1"
|
|
843
|
+
},
|
|
844
|
+
{
|
|
845
|
+
args: [
|
|
846
|
+
{
|
|
847
|
+
label: "to",
|
|
848
|
+
type: {
|
|
849
|
+
displayName: [
|
|
850
|
+
"AccountId"
|
|
851
|
+
],
|
|
852
|
+
type: 0
|
|
853
|
+
}
|
|
854
|
+
},
|
|
855
|
+
{
|
|
856
|
+
label: "value",
|
|
857
|
+
type: {
|
|
858
|
+
displayName: [
|
|
859
|
+
"Balance"
|
|
860
|
+
],
|
|
861
|
+
type: 3
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
],
|
|
865
|
+
default: false,
|
|
866
|
+
docs: [
|
|
867
|
+
" Mints new tokens and adds them to an account's balance; only callable by controller."
|
|
868
|
+
],
|
|
869
|
+
label: "mint",
|
|
870
|
+
mutates: true,
|
|
871
|
+
payable: false,
|
|
872
|
+
returnType: {
|
|
873
|
+
displayName: [
|
|
874
|
+
"ink",
|
|
875
|
+
"MessageResult"
|
|
876
|
+
],
|
|
877
|
+
type: 18
|
|
878
|
+
},
|
|
879
|
+
selector: "0xcfdd9aa2"
|
|
880
|
+
},
|
|
881
|
+
{
|
|
882
|
+
args: [
|
|
883
|
+
{
|
|
884
|
+
label: "from",
|
|
885
|
+
type: {
|
|
886
|
+
displayName: [
|
|
887
|
+
"AccountId"
|
|
888
|
+
],
|
|
889
|
+
type: 0
|
|
890
|
+
}
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
label: "value",
|
|
894
|
+
type: {
|
|
895
|
+
displayName: [
|
|
896
|
+
"Balance"
|
|
897
|
+
],
|
|
898
|
+
type: 3
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
],
|
|
902
|
+
default: false,
|
|
903
|
+
docs: [
|
|
904
|
+
" Burns tokens from an account, reducing the total supply; only callable by controller."
|
|
905
|
+
],
|
|
906
|
+
label: "burn",
|
|
907
|
+
mutates: true,
|
|
908
|
+
payable: false,
|
|
909
|
+
returnType: {
|
|
910
|
+
displayName: [
|
|
911
|
+
"ink",
|
|
912
|
+
"MessageResult"
|
|
913
|
+
],
|
|
914
|
+
type: 18
|
|
915
|
+
},
|
|
916
|
+
selector: "0xb1efc17b"
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
args: [
|
|
920
|
+
{
|
|
921
|
+
label: "spender",
|
|
922
|
+
type: {
|
|
923
|
+
displayName: [
|
|
924
|
+
"AccountId"
|
|
925
|
+
],
|
|
926
|
+
type: 0
|
|
927
|
+
}
|
|
928
|
+
},
|
|
929
|
+
{
|
|
930
|
+
label: "value",
|
|
931
|
+
type: {
|
|
932
|
+
displayName: [
|
|
933
|
+
"Balance"
|
|
934
|
+
],
|
|
935
|
+
type: 3
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
],
|
|
939
|
+
default: false,
|
|
940
|
+
docs: [
|
|
941
|
+
" Approves a spender to transfer up to a specified amount of tokens on behalf of the caller."
|
|
942
|
+
],
|
|
943
|
+
label: "approve",
|
|
944
|
+
mutates: true,
|
|
945
|
+
payable: false,
|
|
946
|
+
returnType: {
|
|
947
|
+
displayName: [
|
|
948
|
+
"ink",
|
|
949
|
+
"MessageResult"
|
|
950
|
+
],
|
|
951
|
+
type: 18
|
|
952
|
+
},
|
|
953
|
+
selector: "0x681266a0"
|
|
954
|
+
},
|
|
955
|
+
{
|
|
956
|
+
args: [
|
|
957
|
+
{
|
|
958
|
+
label: "from",
|
|
959
|
+
type: {
|
|
960
|
+
displayName: [
|
|
961
|
+
"AccountId"
|
|
962
|
+
],
|
|
963
|
+
type: 0
|
|
964
|
+
}
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
label: "to",
|
|
968
|
+
type: {
|
|
969
|
+
displayName: [
|
|
970
|
+
"AccountId"
|
|
971
|
+
],
|
|
972
|
+
type: 0
|
|
973
|
+
}
|
|
974
|
+
},
|
|
975
|
+
{
|
|
976
|
+
label: "value",
|
|
977
|
+
type: {
|
|
978
|
+
displayName: [
|
|
979
|
+
"Balance"
|
|
980
|
+
],
|
|
981
|
+
type: 3
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
],
|
|
985
|
+
default: false,
|
|
986
|
+
docs: [
|
|
987
|
+
" Transfers tokens on behalf of an owner account to a recipient, using the caller's allowance."
|
|
988
|
+
],
|
|
989
|
+
label: "transfer_from",
|
|
990
|
+
mutates: true,
|
|
991
|
+
payable: false,
|
|
992
|
+
returnType: {
|
|
993
|
+
displayName: [
|
|
994
|
+
"ink",
|
|
995
|
+
"MessageResult"
|
|
996
|
+
],
|
|
997
|
+
type: 18
|
|
998
|
+
},
|
|
999
|
+
selector: "0x0b396f18"
|
|
1000
|
+
}
|
|
1001
|
+
]
|
|
1002
|
+
},
|
|
1003
|
+
storage: {
|
|
1004
|
+
root: {
|
|
1005
|
+
layout: {
|
|
1006
|
+
struct: {
|
|
1007
|
+
fields: [
|
|
1008
|
+
{
|
|
1009
|
+
layout: {
|
|
1010
|
+
leaf: {
|
|
1011
|
+
key: "0x00000000",
|
|
1012
|
+
ty: 0
|
|
1013
|
+
}
|
|
1014
|
+
},
|
|
1015
|
+
name: "controller"
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
layout: {
|
|
1019
|
+
leaf: {
|
|
1020
|
+
key: "0x00000000",
|
|
1021
|
+
ty: 3
|
|
1022
|
+
}
|
|
1023
|
+
},
|
|
1024
|
+
name: "total_supply"
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
layout: {
|
|
1028
|
+
root: {
|
|
1029
|
+
layout: {
|
|
1030
|
+
leaf: {
|
|
1031
|
+
key: "0xa49198b1",
|
|
1032
|
+
ty: 3
|
|
1033
|
+
}
|
|
1034
|
+
},
|
|
1035
|
+
root_key: "0xa49198b1",
|
|
1036
|
+
ty: 4
|
|
1037
|
+
}
|
|
1038
|
+
},
|
|
1039
|
+
name: "balances"
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
layout: {
|
|
1043
|
+
root: {
|
|
1044
|
+
layout: {
|
|
1045
|
+
leaf: {
|
|
1046
|
+
key: "0x1c6265af",
|
|
1047
|
+
ty: 3
|
|
1048
|
+
}
|
|
1049
|
+
},
|
|
1050
|
+
root_key: "0x1c6265af",
|
|
1051
|
+
ty: 9
|
|
1052
|
+
}
|
|
1053
|
+
},
|
|
1054
|
+
name: "allowances"
|
|
1055
|
+
}
|
|
1056
|
+
],
|
|
1057
|
+
name: "TusdtErc20"
|
|
1058
|
+
}
|
|
1059
|
+
},
|
|
1060
|
+
root_key: "0x00000000",
|
|
1061
|
+
ty: 13
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
types: [
|
|
1065
|
+
{
|
|
1066
|
+
id: 0,
|
|
1067
|
+
type: {
|
|
1068
|
+
def: {
|
|
1069
|
+
composite: {
|
|
1070
|
+
fields: [
|
|
1071
|
+
{
|
|
1072
|
+
type: 1,
|
|
1073
|
+
typeName: "[u8; 32]"
|
|
1074
|
+
}
|
|
1075
|
+
]
|
|
1076
|
+
}
|
|
1077
|
+
},
|
|
1078
|
+
path: [
|
|
1079
|
+
"ink_primitives",
|
|
1080
|
+
"types",
|
|
1081
|
+
"AccountId"
|
|
1082
|
+
]
|
|
1083
|
+
}
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
id: 1,
|
|
1087
|
+
type: {
|
|
1088
|
+
def: {
|
|
1089
|
+
array: {
|
|
1090
|
+
len: 32,
|
|
1091
|
+
type: 2
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
},
|
|
1096
|
+
{
|
|
1097
|
+
id: 2,
|
|
1098
|
+
type: {
|
|
1099
|
+
def: {
|
|
1100
|
+
primitive: "u8"
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
},
|
|
1104
|
+
{
|
|
1105
|
+
id: 3,
|
|
1106
|
+
type: {
|
|
1107
|
+
def: {
|
|
1108
|
+
primitive: "u64"
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
1112
|
+
{
|
|
1113
|
+
id: 4,
|
|
1114
|
+
type: {
|
|
1115
|
+
def: {
|
|
1116
|
+
composite: {}
|
|
1117
|
+
},
|
|
1118
|
+
params: [
|
|
1119
|
+
{
|
|
1120
|
+
name: "K",
|
|
1121
|
+
type: 0
|
|
1122
|
+
},
|
|
1123
|
+
{
|
|
1124
|
+
name: "V",
|
|
1125
|
+
type: 3
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
name: "KeyType",
|
|
1129
|
+
type: 5
|
|
1130
|
+
}
|
|
1131
|
+
],
|
|
1132
|
+
path: [
|
|
1133
|
+
"ink_storage",
|
|
1134
|
+
"lazy",
|
|
1135
|
+
"mapping",
|
|
1136
|
+
"Mapping"
|
|
1137
|
+
]
|
|
1138
|
+
}
|
|
1139
|
+
},
|
|
1140
|
+
{
|
|
1141
|
+
id: 5,
|
|
1142
|
+
type: {
|
|
1143
|
+
def: {
|
|
1144
|
+
composite: {}
|
|
1145
|
+
},
|
|
1146
|
+
params: [
|
|
1147
|
+
{
|
|
1148
|
+
name: "L",
|
|
1149
|
+
type: 6
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
name: "R",
|
|
1153
|
+
type: 7
|
|
1154
|
+
}
|
|
1155
|
+
],
|
|
1156
|
+
path: [
|
|
1157
|
+
"ink_storage_traits",
|
|
1158
|
+
"impls",
|
|
1159
|
+
"ResolverKey"
|
|
1160
|
+
]
|
|
1161
|
+
}
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
id: 6,
|
|
1165
|
+
type: {
|
|
1166
|
+
def: {
|
|
1167
|
+
composite: {}
|
|
1168
|
+
},
|
|
1169
|
+
path: [
|
|
1170
|
+
"ink_storage_traits",
|
|
1171
|
+
"impls",
|
|
1172
|
+
"AutoKey"
|
|
1173
|
+
]
|
|
1174
|
+
}
|
|
1175
|
+
},
|
|
1176
|
+
{
|
|
1177
|
+
id: 7,
|
|
1178
|
+
type: {
|
|
1179
|
+
def: {
|
|
1180
|
+
composite: {}
|
|
1181
|
+
},
|
|
1182
|
+
params: [
|
|
1183
|
+
{
|
|
1184
|
+
name: "ParentKey",
|
|
1185
|
+
type: 8
|
|
1186
|
+
}
|
|
1187
|
+
],
|
|
1188
|
+
path: [
|
|
1189
|
+
"ink_storage_traits",
|
|
1190
|
+
"impls",
|
|
1191
|
+
"ManualKey"
|
|
1192
|
+
]
|
|
1193
|
+
}
|
|
1194
|
+
},
|
|
1195
|
+
{
|
|
1196
|
+
id: 8,
|
|
1197
|
+
type: {
|
|
1198
|
+
def: {
|
|
1199
|
+
tuple: []
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
},
|
|
1203
|
+
{
|
|
1204
|
+
id: 9,
|
|
1205
|
+
type: {
|
|
1206
|
+
def: {
|
|
1207
|
+
composite: {}
|
|
1208
|
+
},
|
|
1209
|
+
params: [
|
|
1210
|
+
{
|
|
1211
|
+
name: "K",
|
|
1212
|
+
type: 10
|
|
1213
|
+
},
|
|
1214
|
+
{
|
|
1215
|
+
name: "V",
|
|
1216
|
+
type: 3
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
name: "KeyType",
|
|
1220
|
+
type: 11
|
|
1221
|
+
}
|
|
1222
|
+
],
|
|
1223
|
+
path: [
|
|
1224
|
+
"ink_storage",
|
|
1225
|
+
"lazy",
|
|
1226
|
+
"mapping",
|
|
1227
|
+
"Mapping"
|
|
1228
|
+
]
|
|
1229
|
+
}
|
|
1230
|
+
},
|
|
1231
|
+
{
|
|
1232
|
+
id: 10,
|
|
1233
|
+
type: {
|
|
1234
|
+
def: {
|
|
1235
|
+
tuple: [
|
|
1236
|
+
0,
|
|
1237
|
+
0
|
|
1238
|
+
]
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
},
|
|
1242
|
+
{
|
|
1243
|
+
id: 11,
|
|
1244
|
+
type: {
|
|
1245
|
+
def: {
|
|
1246
|
+
composite: {}
|
|
1247
|
+
},
|
|
1248
|
+
params: [
|
|
1249
|
+
{
|
|
1250
|
+
name: "L",
|
|
1251
|
+
type: 6
|
|
1252
|
+
},
|
|
1253
|
+
{
|
|
1254
|
+
name: "R",
|
|
1255
|
+
type: 12
|
|
1256
|
+
}
|
|
1257
|
+
],
|
|
1258
|
+
path: [
|
|
1259
|
+
"ink_storage_traits",
|
|
1260
|
+
"impls",
|
|
1261
|
+
"ResolverKey"
|
|
1262
|
+
]
|
|
1263
|
+
}
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
id: 12,
|
|
1267
|
+
type: {
|
|
1268
|
+
def: {
|
|
1269
|
+
composite: {}
|
|
1270
|
+
},
|
|
1271
|
+
params: [
|
|
1272
|
+
{
|
|
1273
|
+
name: "ParentKey",
|
|
1274
|
+
type: 8
|
|
1275
|
+
}
|
|
1276
|
+
],
|
|
1277
|
+
path: [
|
|
1278
|
+
"ink_storage_traits",
|
|
1279
|
+
"impls",
|
|
1280
|
+
"ManualKey"
|
|
1281
|
+
]
|
|
1282
|
+
}
|
|
1283
|
+
},
|
|
1284
|
+
{
|
|
1285
|
+
id: 13,
|
|
1286
|
+
type: {
|
|
1287
|
+
def: {
|
|
1288
|
+
composite: {
|
|
1289
|
+
fields: [
|
|
1290
|
+
{
|
|
1291
|
+
name: "controller",
|
|
1292
|
+
type: 0,
|
|
1293
|
+
typeName: "<AccountId as::ink::storage::traits::AutoStorableHint<::ink::\nstorage::traits::ManualKey<3589911795u32, ()>,>>::Type"
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
name: "total_supply",
|
|
1297
|
+
type: 3,
|
|
1298
|
+
typeName: "<Balance as::ink::storage::traits::AutoStorableHint<::ink::\nstorage::traits::ManualKey<2456737585u32, ()>,>>::Type"
|
|
1299
|
+
},
|
|
1300
|
+
{
|
|
1301
|
+
name: "balances",
|
|
1302
|
+
type: 4,
|
|
1303
|
+
typeName: "<Mapping<AccountId, Balance> as::ink::storage::traits::\nAutoStorableHint<::ink::storage::traits::ManualKey<2979565988u32,\n()>,>>::Type"
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
name: "allowances",
|
|
1307
|
+
type: 9,
|
|
1308
|
+
typeName: "<Mapping<(AccountId, AccountId), Balance> as::ink::storage::traits\n::AutoStorableHint<::ink::storage::traits::ManualKey<\n2942657052u32, ()>,>>::Type"
|
|
1309
|
+
}
|
|
1310
|
+
]
|
|
1311
|
+
}
|
|
1312
|
+
},
|
|
1313
|
+
path: [
|
|
1314
|
+
"tusdt_erc20",
|
|
1315
|
+
"tusdt",
|
|
1316
|
+
"TusdtErc20"
|
|
1317
|
+
]
|
|
1318
|
+
}
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
id: 14,
|
|
1322
|
+
type: {
|
|
1323
|
+
def: {
|
|
1324
|
+
variant: {
|
|
1325
|
+
variants: [
|
|
1326
|
+
{
|
|
1327
|
+
fields: [
|
|
1328
|
+
{
|
|
1329
|
+
type: 8
|
|
1330
|
+
}
|
|
1331
|
+
],
|
|
1332
|
+
index: 0,
|
|
1333
|
+
name: "Ok"
|
|
1334
|
+
},
|
|
1335
|
+
{
|
|
1336
|
+
fields: [
|
|
1337
|
+
{
|
|
1338
|
+
type: 15
|
|
1339
|
+
}
|
|
1340
|
+
],
|
|
1341
|
+
index: 1,
|
|
1342
|
+
name: "Err"
|
|
1343
|
+
}
|
|
1344
|
+
]
|
|
1345
|
+
}
|
|
1346
|
+
},
|
|
1347
|
+
params: [
|
|
1348
|
+
{
|
|
1349
|
+
name: "T",
|
|
1350
|
+
type: 8
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
name: "E",
|
|
1354
|
+
type: 15
|
|
1355
|
+
}
|
|
1356
|
+
],
|
|
1357
|
+
path: [
|
|
1358
|
+
"Result"
|
|
1359
|
+
]
|
|
1360
|
+
}
|
|
1361
|
+
},
|
|
1362
|
+
{
|
|
1363
|
+
id: 15,
|
|
1364
|
+
type: {
|
|
1365
|
+
def: {
|
|
1366
|
+
variant: {
|
|
1367
|
+
variants: [
|
|
1368
|
+
{
|
|
1369
|
+
index: 1,
|
|
1370
|
+
name: "CouldNotReadInput"
|
|
1371
|
+
}
|
|
1372
|
+
]
|
|
1373
|
+
}
|
|
1374
|
+
},
|
|
1375
|
+
path: [
|
|
1376
|
+
"ink_primitives",
|
|
1377
|
+
"LangError"
|
|
1378
|
+
]
|
|
1379
|
+
}
|
|
1380
|
+
},
|
|
1381
|
+
{
|
|
1382
|
+
id: 16,
|
|
1383
|
+
type: {
|
|
1384
|
+
def: {
|
|
1385
|
+
variant: {
|
|
1386
|
+
variants: [
|
|
1387
|
+
{
|
|
1388
|
+
fields: [
|
|
1389
|
+
{
|
|
1390
|
+
type: 0
|
|
1391
|
+
}
|
|
1392
|
+
],
|
|
1393
|
+
index: 0,
|
|
1394
|
+
name: "Ok"
|
|
1395
|
+
},
|
|
1396
|
+
{
|
|
1397
|
+
fields: [
|
|
1398
|
+
{
|
|
1399
|
+
type: 15
|
|
1400
|
+
}
|
|
1401
|
+
],
|
|
1402
|
+
index: 1,
|
|
1403
|
+
name: "Err"
|
|
1404
|
+
}
|
|
1405
|
+
]
|
|
1406
|
+
}
|
|
1407
|
+
},
|
|
1408
|
+
params: [
|
|
1409
|
+
{
|
|
1410
|
+
name: "T",
|
|
1411
|
+
type: 0
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
name: "E",
|
|
1415
|
+
type: 15
|
|
1416
|
+
}
|
|
1417
|
+
],
|
|
1418
|
+
path: [
|
|
1419
|
+
"Result"
|
|
1420
|
+
]
|
|
1421
|
+
}
|
|
1422
|
+
},
|
|
1423
|
+
{
|
|
1424
|
+
id: 17,
|
|
1425
|
+
type: {
|
|
1426
|
+
def: {
|
|
1427
|
+
variant: {
|
|
1428
|
+
variants: [
|
|
1429
|
+
{
|
|
1430
|
+
fields: [
|
|
1431
|
+
{
|
|
1432
|
+
type: 3
|
|
1433
|
+
}
|
|
1434
|
+
],
|
|
1435
|
+
index: 0,
|
|
1436
|
+
name: "Ok"
|
|
1437
|
+
},
|
|
1438
|
+
{
|
|
1439
|
+
fields: [
|
|
1440
|
+
{
|
|
1441
|
+
type: 15
|
|
1442
|
+
}
|
|
1443
|
+
],
|
|
1444
|
+
index: 1,
|
|
1445
|
+
name: "Err"
|
|
1446
|
+
}
|
|
1447
|
+
]
|
|
1448
|
+
}
|
|
1449
|
+
},
|
|
1450
|
+
params: [
|
|
1451
|
+
{
|
|
1452
|
+
name: "T",
|
|
1453
|
+
type: 3
|
|
1454
|
+
},
|
|
1455
|
+
{
|
|
1456
|
+
name: "E",
|
|
1457
|
+
type: 15
|
|
1458
|
+
}
|
|
1459
|
+
],
|
|
1460
|
+
path: [
|
|
1461
|
+
"Result"
|
|
1462
|
+
]
|
|
1463
|
+
}
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
id: 18,
|
|
1467
|
+
type: {
|
|
1468
|
+
def: {
|
|
1469
|
+
variant: {
|
|
1470
|
+
variants: [
|
|
1471
|
+
{
|
|
1472
|
+
fields: [
|
|
1473
|
+
{
|
|
1474
|
+
type: 19
|
|
1475
|
+
}
|
|
1476
|
+
],
|
|
1477
|
+
index: 0,
|
|
1478
|
+
name: "Ok"
|
|
1479
|
+
},
|
|
1480
|
+
{
|
|
1481
|
+
fields: [
|
|
1482
|
+
{
|
|
1483
|
+
type: 15
|
|
1484
|
+
}
|
|
1485
|
+
],
|
|
1486
|
+
index: 1,
|
|
1487
|
+
name: "Err"
|
|
1488
|
+
}
|
|
1489
|
+
]
|
|
1490
|
+
}
|
|
1491
|
+
},
|
|
1492
|
+
params: [
|
|
1493
|
+
{
|
|
1494
|
+
name: "T",
|
|
1495
|
+
type: 19
|
|
1496
|
+
},
|
|
1497
|
+
{
|
|
1498
|
+
name: "E",
|
|
1499
|
+
type: 15
|
|
1500
|
+
}
|
|
1501
|
+
],
|
|
1502
|
+
path: [
|
|
1503
|
+
"Result"
|
|
1504
|
+
]
|
|
1505
|
+
}
|
|
1506
|
+
},
|
|
1507
|
+
{
|
|
1508
|
+
id: 19,
|
|
1509
|
+
type: {
|
|
1510
|
+
def: {
|
|
1511
|
+
variant: {
|
|
1512
|
+
variants: [
|
|
1513
|
+
{
|
|
1514
|
+
fields: [
|
|
1515
|
+
{
|
|
1516
|
+
type: 8
|
|
1517
|
+
}
|
|
1518
|
+
],
|
|
1519
|
+
index: 0,
|
|
1520
|
+
name: "Ok"
|
|
1521
|
+
},
|
|
1522
|
+
{
|
|
1523
|
+
fields: [
|
|
1524
|
+
{
|
|
1525
|
+
type: 20
|
|
1526
|
+
}
|
|
1527
|
+
],
|
|
1528
|
+
index: 1,
|
|
1529
|
+
name: "Err"
|
|
1530
|
+
}
|
|
1531
|
+
]
|
|
1532
|
+
}
|
|
1533
|
+
},
|
|
1534
|
+
params: [
|
|
1535
|
+
{
|
|
1536
|
+
name: "T",
|
|
1537
|
+
type: 8
|
|
1538
|
+
},
|
|
1539
|
+
{
|
|
1540
|
+
name: "E",
|
|
1541
|
+
type: 20
|
|
1542
|
+
}
|
|
1543
|
+
],
|
|
1544
|
+
path: [
|
|
1545
|
+
"Result"
|
|
1546
|
+
]
|
|
1547
|
+
}
|
|
1548
|
+
},
|
|
1549
|
+
{
|
|
1550
|
+
id: 20,
|
|
1551
|
+
type: {
|
|
1552
|
+
def: {
|
|
1553
|
+
variant: {
|
|
1554
|
+
variants: [
|
|
1555
|
+
{
|
|
1556
|
+
index: 0,
|
|
1557
|
+
name: "InsufficientBalance"
|
|
1558
|
+
},
|
|
1559
|
+
{
|
|
1560
|
+
index: 1,
|
|
1561
|
+
name: "InsufficientAllowance"
|
|
1562
|
+
},
|
|
1563
|
+
{
|
|
1564
|
+
index: 2,
|
|
1565
|
+
name: "NotController"
|
|
1566
|
+
}
|
|
1567
|
+
]
|
|
1568
|
+
}
|
|
1569
|
+
},
|
|
1570
|
+
path: [
|
|
1571
|
+
"tusdt_erc20",
|
|
1572
|
+
"tusdt",
|
|
1573
|
+
"Error"
|
|
1574
|
+
]
|
|
1575
|
+
}
|
|
1576
|
+
},
|
|
1577
|
+
{
|
|
1578
|
+
id: 21,
|
|
1579
|
+
type: {
|
|
1580
|
+
def: {
|
|
1581
|
+
variant: {
|
|
1582
|
+
variants: [
|
|
1583
|
+
{
|
|
1584
|
+
index: 0,
|
|
1585
|
+
name: "None"
|
|
1586
|
+
},
|
|
1587
|
+
{
|
|
1588
|
+
fields: [
|
|
1589
|
+
{
|
|
1590
|
+
type: 0
|
|
1591
|
+
}
|
|
1592
|
+
],
|
|
1593
|
+
index: 1,
|
|
1594
|
+
name: "Some"
|
|
1595
|
+
}
|
|
1596
|
+
]
|
|
1597
|
+
}
|
|
1598
|
+
},
|
|
1599
|
+
params: [
|
|
1600
|
+
{
|
|
1601
|
+
name: "T",
|
|
1602
|
+
type: 0
|
|
1603
|
+
}
|
|
1604
|
+
],
|
|
1605
|
+
path: [
|
|
1606
|
+
"Option"
|
|
1607
|
+
]
|
|
1608
|
+
}
|
|
1609
|
+
},
|
|
1610
|
+
{
|
|
1611
|
+
id: 22,
|
|
1612
|
+
type: {
|
|
1613
|
+
def: {
|
|
1614
|
+
composite: {
|
|
1615
|
+
fields: [
|
|
1616
|
+
{
|
|
1617
|
+
type: 1,
|
|
1618
|
+
typeName: "[u8; 32]"
|
|
1619
|
+
}
|
|
1620
|
+
]
|
|
1621
|
+
}
|
|
1622
|
+
},
|
|
1623
|
+
path: [
|
|
1624
|
+
"ink_primitives",
|
|
1625
|
+
"types",
|
|
1626
|
+
"Hash"
|
|
1627
|
+
]
|
|
1628
|
+
}
|
|
1629
|
+
},
|
|
1630
|
+
{
|
|
1631
|
+
id: 23,
|
|
1632
|
+
type: {
|
|
1633
|
+
def: {
|
|
1634
|
+
primitive: "u32"
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
},
|
|
1638
|
+
{
|
|
1639
|
+
id: 24,
|
|
1640
|
+
type: {
|
|
1641
|
+
def: {
|
|
1642
|
+
variant: {}
|
|
1643
|
+
},
|
|
1644
|
+
path: [
|
|
1645
|
+
"tusdt_env",
|
|
1646
|
+
"RuntimeReadWrite"
|
|
1647
|
+
]
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
],
|
|
1651
|
+
version: 5
|
|
1652
|
+
};
|
|
1653
|
+
|
|
1654
|
+
// src/contract/tusdt-contract.ts
|
|
1655
|
+
var TusdtContract = class _TusdtContract {
|
|
1656
|
+
/** The underlying Dedot typed contract instance */
|
|
1657
|
+
contract;
|
|
1658
|
+
/** The Dedot client (stored for event subscriptions) */
|
|
1659
|
+
client;
|
|
1660
|
+
/**
|
|
1661
|
+
* Create a TusdtContract attached to a deployed TUSDT ERC20 contract.
|
|
1662
|
+
*
|
|
1663
|
+
* @param client - A connected Dedot client instance (DedotClient or LegacyClient).
|
|
1664
|
+
* For nodes using legacy JSON-RPC, create with `DedotClient.legacy(provider)`.
|
|
1665
|
+
* The user is responsible for creating and managing the client lifecycle.
|
|
1666
|
+
* @param contractAddress - The SS58 address of the deployed contract.
|
|
1667
|
+
* @param options - Optional configuration.
|
|
1668
|
+
*/
|
|
1669
|
+
constructor(client, contractAddress, options) {
|
|
1670
|
+
this.client = client;
|
|
1671
|
+
this.contract = new Contract(
|
|
1672
|
+
client,
|
|
1673
|
+
tusdt_erc20_default,
|
|
1674
|
+
contractAddress,
|
|
1675
|
+
{ defaultCaller: options?.defaultCaller ?? ZERO_ADDRESS }
|
|
1676
|
+
);
|
|
1677
|
+
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Factory: create from user-provided metadata JSON.
|
|
1680
|
+
*
|
|
1681
|
+
* Use this when the metadata JSON is loaded externally (e.g., in browser builds
|
|
1682
|
+
* where JSON import paths may differ, or when using a custom contract build).
|
|
1683
|
+
*/
|
|
1684
|
+
static fromMetadata(client, contractAddress, metadata, options) {
|
|
1685
|
+
const instance = Object.create(_TusdtContract.prototype);
|
|
1686
|
+
instance.client = client;
|
|
1687
|
+
instance.contract = new Contract(
|
|
1688
|
+
client,
|
|
1689
|
+
metadata,
|
|
1690
|
+
contractAddress,
|
|
1691
|
+
{ defaultCaller: options?.defaultCaller ?? ZERO_ADDRESS }
|
|
1692
|
+
);
|
|
1693
|
+
return instance;
|
|
1694
|
+
}
|
|
1695
|
+
// ─── Read-Only Queries ────────────────────────────────────────
|
|
1696
|
+
/**
|
|
1697
|
+
* Returns the controller account address.
|
|
1698
|
+
* The controller is authorized to mint/burn tokens.
|
|
1699
|
+
*/
|
|
1700
|
+
controller() {
|
|
1701
|
+
return queryController(this.contract);
|
|
1702
|
+
}
|
|
1703
|
+
/**
|
|
1704
|
+
* Returns the total supply of tokens in circulation.
|
|
1705
|
+
* Returns bigint (u64).
|
|
1706
|
+
*/
|
|
1707
|
+
totalSupply() {
|
|
1708
|
+
return queryTotalSupply(this.contract);
|
|
1709
|
+
}
|
|
1710
|
+
/**
|
|
1711
|
+
* Returns the token balance of the specified account.
|
|
1712
|
+
* Returns 0n if the account has no balance.
|
|
1713
|
+
*/
|
|
1714
|
+
balanceOf(owner) {
|
|
1715
|
+
return queryBalanceOf(this.contract, owner);
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1718
|
+
* Returns the remaining allowance that spender can withdraw from owner.
|
|
1719
|
+
* Returns 0n if no allowance has been set.
|
|
1720
|
+
*/
|
|
1721
|
+
allowance(owner, spender) {
|
|
1722
|
+
return queryAllowance(this.contract, owner, spender);
|
|
1723
|
+
}
|
|
1724
|
+
// ─── State-Changing Transactions ──────────────────────────────
|
|
1725
|
+
/**
|
|
1726
|
+
* Transfer tokens from the signer's account to a recipient.
|
|
1727
|
+
*
|
|
1728
|
+
* Performs a dry-run first to check for errors and estimate gas.
|
|
1729
|
+
* Self-transfers and zero-value transfers are allowed.
|
|
1730
|
+
*
|
|
1731
|
+
* @throws InsufficientBalanceError if signer has insufficient balance
|
|
1732
|
+
* @throws ValidationError if inputs are invalid or would cause overflow
|
|
1733
|
+
*/
|
|
1734
|
+
transfer(signer, to, value, options) {
|
|
1735
|
+
return executeTransfer(this.contract, signer, to, value, options);
|
|
1736
|
+
}
|
|
1737
|
+
/**
|
|
1738
|
+
* Approve a spender to withdraw up to `value` tokens from the signer's account.
|
|
1739
|
+
*
|
|
1740
|
+
* WARNING: Uses set-overwrite pattern (standard ERC20). Subject to front-running attack.
|
|
1741
|
+
* Use `safeApprove()` for safer approval changes.
|
|
1742
|
+
*
|
|
1743
|
+
* @throws ValidationError if inputs are invalid
|
|
1744
|
+
*/
|
|
1745
|
+
approve(signer, spender, value, options) {
|
|
1746
|
+
return executeApprove(this.contract, signer, spender, value, options);
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* Transfer tokens from one account to another using the signer's allowance.
|
|
1750
|
+
*
|
|
1751
|
+
* The signer must have been granted sufficient allowance by the `from` account.
|
|
1752
|
+
* On success, the allowance is decreased by `value`.
|
|
1753
|
+
* On failure (insufficient balance), the allowance is NOT decreased.
|
|
1754
|
+
*
|
|
1755
|
+
* @throws InsufficientAllowanceError if signer has insufficient allowance
|
|
1756
|
+
* @throws InsufficientBalanceError if `from` has insufficient balance
|
|
1757
|
+
* @throws ValidationError if inputs are invalid or would cause overflow
|
|
1758
|
+
*/
|
|
1759
|
+
transferFrom(signer, from, to, value, options) {
|
|
1760
|
+
return executeTransferFrom(this.contract, signer, from, to, value, options);
|
|
1761
|
+
}
|
|
1762
|
+
/**
|
|
1763
|
+
* Safe approval that mitigates the ERC20 approve front-running attack.
|
|
1764
|
+
*
|
|
1765
|
+
* If the current allowance > 0 and newValue > 0, this first sets the
|
|
1766
|
+
* allowance to 0, then sets it to the desired value.
|
|
1767
|
+
*
|
|
1768
|
+
* @throws ValidationError if inputs are invalid
|
|
1769
|
+
*/
|
|
1770
|
+
safeApprove(signer, spender, newValue, options) {
|
|
1771
|
+
return safeApprove(this.contract, signer, spender, newValue, options);
|
|
1772
|
+
}
|
|
1773
|
+
// ─── Event Subscriptions ──────────────────────────────────────
|
|
1774
|
+
/**
|
|
1775
|
+
* Subscribe to all Transfer events emitted by this contract.
|
|
1776
|
+
* Includes mints (from=null), burns (to=null), and regular transfers.
|
|
1777
|
+
*
|
|
1778
|
+
* @param options - Optional. Pass `onError` to receive errors instead of silent skipping.
|
|
1779
|
+
* @returns A function to unsubscribe from the event stream.
|
|
1780
|
+
*/
|
|
1781
|
+
onTransfer(callback, options) {
|
|
1782
|
+
return subscribeTransfer(this.client, this.contract, callback, options);
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Subscribe to all Approval events emitted by this contract.
|
|
1786
|
+
*
|
|
1787
|
+
* @param options - Optional. Pass `onError` to receive errors instead of silent skipping.
|
|
1788
|
+
* @returns A function to unsubscribe from the event stream.
|
|
1789
|
+
*/
|
|
1790
|
+
onApproval(callback, options) {
|
|
1791
|
+
return subscribeApproval(this.client, this.contract, callback, options);
|
|
1792
|
+
}
|
|
1793
|
+
/**
|
|
1794
|
+
* Subscribe to Transfer events where a specific account is the sender.
|
|
1795
|
+
*
|
|
1796
|
+
* @param account - SS58 address of the sender to filter for
|
|
1797
|
+
* @param options - Optional. Pass `onError` to receive errors instead of silent skipping.
|
|
1798
|
+
* @returns A function to unsubscribe from the event stream.
|
|
1799
|
+
*/
|
|
1800
|
+
onTransferFrom(account, callback, options) {
|
|
1801
|
+
return subscribeTransferFrom(this.client, this.contract, account, callback, options);
|
|
1802
|
+
}
|
|
1803
|
+
/**
|
|
1804
|
+
* Subscribe to Transfer events where a specific account is the recipient.
|
|
1805
|
+
*
|
|
1806
|
+
* @param account - SS58 address of the recipient to filter for
|
|
1807
|
+
* @param options - Optional. Pass `onError` to receive errors instead of silent skipping.
|
|
1808
|
+
* @returns A function to unsubscribe from the event stream.
|
|
1809
|
+
*/
|
|
1810
|
+
onTransferTo(account, callback, options) {
|
|
1811
|
+
return subscribeTransferTo(this.client, this.contract, account, callback, options);
|
|
1812
|
+
}
|
|
1813
|
+
// ─── Finalized Event Subscriptions ─────────────────────────────
|
|
1814
|
+
/**
|
|
1815
|
+
* Subscribe to all Transfer events on finalized blocks.
|
|
1816
|
+
*
|
|
1817
|
+
* Finalized blocks are immutable (no reorg risk), making this suitable for
|
|
1818
|
+
* payment detection and reconciliation. Events include block number and
|
|
1819
|
+
* event index within the block.
|
|
1820
|
+
*
|
|
1821
|
+
* For a full production payment listener with reconnection, deduplication,
|
|
1822
|
+
* and address filtering, use `TusdtPaymentListener` from `tusdt-sdk/server`.
|
|
1823
|
+
*
|
|
1824
|
+
* @param options - Optional. Pass `onError` to receive errors instead of silent skipping.
|
|
1825
|
+
* @returns A function to unsubscribe from the event stream.
|
|
1826
|
+
*/
|
|
1827
|
+
onFinalizedTransfer(callback, options) {
|
|
1828
|
+
return watchFinalizedTransfers(this.client, this.contract, callback, options);
|
|
1829
|
+
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Subscribe to Transfer events to a specific account on finalized blocks.
|
|
1832
|
+
*
|
|
1833
|
+
* @param account - SS58 address of the recipient to filter for
|
|
1834
|
+
* @param options - Optional. Pass `onError` to receive errors instead of silent skipping.
|
|
1835
|
+
* @returns A function to unsubscribe from the event stream.
|
|
1836
|
+
*/
|
|
1837
|
+
onFinalizedTransferTo(account, callback, options) {
|
|
1838
|
+
return watchFinalizedTransfersTo(this.client, this.contract, account, callback, options);
|
|
1839
|
+
}
|
|
1840
|
+
};
|
|
1841
|
+
|
|
1842
|
+
export { ConnectionError, ContractError, DispatchError, DryRunError, InsufficientAllowanceError, InsufficientBalanceError, NotControllerError, TimeoutError, TusdtContract, TusdtSdkError, U64_MAX, ValidationError, ZERO_ADDRESS, ZERO_BALANCE, executeApprove, executeTransfer, executeTransferFrom, getSignerAddress, isKeyringPair, mapContractError, queryAllowance, queryBalanceOf, queryController, queryTotalSupply, safeApprove, subscribeApproval, subscribeTransfer, subscribeTransferFrom, subscribeTransferTo, tusdt_erc20_default, validateAddress, validateBalance, validateOverflowSafe, watchFinalizedTransfers, watchFinalizedTransfersTo };
|
|
1843
|
+
//# sourceMappingURL=chunk-5HS7VSOA.js.map
|
|
1844
|
+
//# sourceMappingURL=chunk-5HS7VSOA.js.map
|