@weblock-wallet/sdk 0.1.51 → 0.1.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +576 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -1
- package/dist/index.d.ts +87 -1
- package/dist/index.js +576 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -105012,21 +105012,19 @@ var UserClient = class {
|
|
|
105012
105012
|
* - { coin: CoinResponse }
|
|
105013
105013
|
* - { data: CoinResponse }
|
|
105014
105014
|
*/
|
|
105015
|
-
// UserClient 클래스 내부의 registerToken()을 아래로 교체
|
|
105016
105015
|
async registerToken(req) {
|
|
105017
|
-
const blockchainId = req.blockchainId
|
|
105018
|
-
const contractAddress =
|
|
105019
|
-
req.contractAddress ?? req.tokenAddress ?? req.address ?? ""
|
|
105020
|
-
).trim().toLowerCase();
|
|
105016
|
+
const blockchainId = req.blockchainId;
|
|
105017
|
+
const contractAddress = this.normalizeAddress(req.contractAddress);
|
|
105021
105018
|
const name2 = req.name;
|
|
105022
105019
|
const symbol = req.symbol;
|
|
105023
105020
|
const decimals = req.decimals;
|
|
105024
105021
|
const candidates = [
|
|
105025
|
-
// 1) 주소만 받는
|
|
105022
|
+
// 1) 최신 스펙으로 바뀌며 "주소만" 받는 경우
|
|
105026
105023
|
{ blockchainId, contractAddress },
|
|
105024
|
+
// 2) 필드명이 tokenAddress / address로 바뀐 경우
|
|
105027
105025
|
{ blockchainId, tokenAddress: contractAddress },
|
|
105028
105026
|
{ blockchainId, address: contractAddress },
|
|
105029
|
-
//
|
|
105027
|
+
// 3) 구 스펙(메타 포함) 유지/필요한 경우
|
|
105030
105028
|
...name2 && symbol && typeof decimals === "number" ? [
|
|
105031
105029
|
{ blockchainId, contractAddress, name: name2, symbol, decimals },
|
|
105032
105030
|
{
|
|
@@ -105038,32 +105036,45 @@ var UserClient = class {
|
|
|
105038
105036
|
},
|
|
105039
105037
|
{ blockchainId, address: contractAddress, name: name2, symbol, decimals }
|
|
105040
105038
|
] : [],
|
|
105041
|
-
//
|
|
105042
|
-
|
|
105043
|
-
|
|
105039
|
+
// 4) blockchainId가 networkId로 바뀐 경우
|
|
105040
|
+
...name2 && symbol && typeof decimals === "number" ? [
|
|
105041
|
+
{
|
|
105042
|
+
networkId: blockchainId,
|
|
105043
|
+
contractAddress,
|
|
105044
|
+
name: name2,
|
|
105045
|
+
symbol,
|
|
105046
|
+
decimals
|
|
105047
|
+
},
|
|
105048
|
+
{
|
|
105049
|
+
networkId: blockchainId,
|
|
105050
|
+
tokenAddress: contractAddress,
|
|
105051
|
+
name: name2,
|
|
105052
|
+
symbol,
|
|
105053
|
+
decimals
|
|
105054
|
+
}
|
|
105055
|
+
] : [{ networkId: blockchainId, contractAddress }]
|
|
105044
105056
|
];
|
|
105045
105057
|
let lastError = null;
|
|
105046
105058
|
for (const body of candidates) {
|
|
105047
105059
|
try {
|
|
105048
105060
|
const res = await this.client.post(
|
|
105049
|
-
|
|
105050
|
-
body
|
|
105051
|
-
{
|
|
105052
|
-
needsAccessToken: true
|
|
105053
|
-
}
|
|
105061
|
+
`${this.baseUrl}/register-token`,
|
|
105062
|
+
body
|
|
105054
105063
|
);
|
|
105055
|
-
const coin = res
|
|
105056
|
-
if (coin?.contractAddress) {
|
|
105057
|
-
|
|
105058
|
-
...coin,
|
|
105059
|
-
contractAddress: String(coin.contractAddress).trim().toLowerCase(),
|
|
105060
|
-
decimals: typeof coin.decimals === "number" ? coin.decimals : Number(coin.decimals)
|
|
105061
|
-
};
|
|
105064
|
+
const coin = this.unwrapCoin(res);
|
|
105065
|
+
if (!coin?.contractAddress) {
|
|
105066
|
+
continue;
|
|
105062
105067
|
}
|
|
105068
|
+
return {
|
|
105069
|
+
...coin,
|
|
105070
|
+
contractAddress: this.normalizeAddress(coin.contractAddress),
|
|
105071
|
+
decimals: Number(coin.decimals)
|
|
105072
|
+
};
|
|
105063
105073
|
} catch (e7) {
|
|
105064
105074
|
lastError = e7;
|
|
105065
|
-
const status = e7
|
|
105066
|
-
if (status === 400 || status ===
|
|
105075
|
+
const status = this.extractStatus(e7);
|
|
105076
|
+
if (status === 400 || status === 422) continue;
|
|
105077
|
+
if (status === 409) continue;
|
|
105067
105078
|
throw e7;
|
|
105068
105079
|
}
|
|
105069
105080
|
}
|
|
@@ -105087,32 +105098,6 @@ var UserClient = class {
|
|
|
105087
105098
|
{ needsAccessToken: true }
|
|
105088
105099
|
);
|
|
105089
105100
|
}
|
|
105090
|
-
// UserClient 클래스 내부에 추가
|
|
105091
|
-
async postAuthed(path, body) {
|
|
105092
|
-
const httpAny = this.client;
|
|
105093
|
-
const headers = (typeof httpAny.getAuthHeaders === "function" ? await httpAny.getAuthHeaders() : typeof httpAny.getHeaders === "function" ? await httpAny.getHeaders() : void 0) ?? void 0;
|
|
105094
|
-
const attempts = [];
|
|
105095
|
-
if (typeof httpAny.post === "function") {
|
|
105096
|
-
attempts.push(() => httpAny.post(path, body, headers));
|
|
105097
|
-
attempts.push(() => httpAny.post(path, body, { headers }));
|
|
105098
|
-
attempts.push(() => httpAny.post(path, body));
|
|
105099
|
-
}
|
|
105100
|
-
if (typeof httpAny.request === "function") {
|
|
105101
|
-
attempts.push(
|
|
105102
|
-
() => httpAny.request({ method: "POST", path, body, headers })
|
|
105103
|
-
);
|
|
105104
|
-
attempts.push(() => httpAny.request("POST", path, body, headers));
|
|
105105
|
-
}
|
|
105106
|
-
let lastError = null;
|
|
105107
|
-
for (const fn of attempts) {
|
|
105108
|
-
try {
|
|
105109
|
-
return await fn();
|
|
105110
|
-
} catch (e7) {
|
|
105111
|
-
lastError = e7;
|
|
105112
|
-
}
|
|
105113
|
-
}
|
|
105114
|
-
throw lastError ?? new Error(`POST ${path} failed`);
|
|
105115
|
-
}
|
|
105116
105101
|
};
|
|
105117
105102
|
|
|
105118
105103
|
// src/clients/api/wallets.ts
|
|
@@ -106239,17 +106224,14 @@ var AssetService = class extends EventEmitter {
|
|
|
106239
106224
|
params.spender,
|
|
106240
106225
|
params.amount
|
|
106241
106226
|
]);
|
|
106242
|
-
const
|
|
106243
|
-
|
|
106244
|
-
|
|
106245
|
-
|
|
106246
|
-
|
|
106247
|
-
to: params.tokenAddress,
|
|
106248
|
-
data
|
|
106249
|
-
}
|
|
106250
|
-
]
|
|
106227
|
+
const txHash = await this.walletService.sendTransaction({
|
|
106228
|
+
to: params.tokenAddress,
|
|
106229
|
+
value: "0",
|
|
106230
|
+
data,
|
|
106231
|
+
chainId
|
|
106251
106232
|
});
|
|
106252
|
-
|
|
106233
|
+
this.trackTransaction(txHash, chainId);
|
|
106234
|
+
return txHash;
|
|
106253
106235
|
} catch (error) {
|
|
106254
106236
|
throw new SDKError(
|
|
106255
106237
|
"Failed to approve token",
|
|
@@ -106332,6 +106314,402 @@ var AssetService = class extends EventEmitter {
|
|
|
106332
106314
|
// }
|
|
106333
106315
|
};
|
|
106334
106316
|
|
|
106317
|
+
// src/core/services/investment.ts
|
|
106318
|
+
var import_ethers4 = require("ethers");
|
|
106319
|
+
|
|
106320
|
+
// src/contract/weblock.ts
|
|
106321
|
+
var RBT_PRIMARY_SALE_ROUTER_ABI = [
|
|
106322
|
+
{
|
|
106323
|
+
inputs: [{ name: "offeringId", type: "uint256" }],
|
|
106324
|
+
name: "offerings",
|
|
106325
|
+
outputs: [
|
|
106326
|
+
{ name: "asset", type: "address" },
|
|
106327
|
+
{ name: "seriesId", type: "uint256" },
|
|
106328
|
+
{ name: "unitPrice", type: "uint256" },
|
|
106329
|
+
{ name: "remainingUnits", type: "uint256" },
|
|
106330
|
+
{ name: "startAt", type: "uint64" },
|
|
106331
|
+
{ name: "endAt", type: "uint64" },
|
|
106332
|
+
{ name: "treasury", type: "address" },
|
|
106333
|
+
{ name: "enabled", type: "bool" }
|
|
106334
|
+
],
|
|
106335
|
+
stateMutability: "view",
|
|
106336
|
+
type: "function"
|
|
106337
|
+
},
|
|
106338
|
+
{
|
|
106339
|
+
inputs: [
|
|
106340
|
+
{ name: "offeringId", type: "uint256" },
|
|
106341
|
+
{ name: "units", type: "uint256" },
|
|
106342
|
+
{ name: "maxCost", type: "uint256" }
|
|
106343
|
+
],
|
|
106344
|
+
name: "buy",
|
|
106345
|
+
outputs: [],
|
|
106346
|
+
stateMutability: "nonpayable",
|
|
106347
|
+
type: "function"
|
|
106348
|
+
}
|
|
106349
|
+
];
|
|
106350
|
+
var RBT_PROPERTY_TOKEN_ABI = [
|
|
106351
|
+
{
|
|
106352
|
+
inputs: [
|
|
106353
|
+
{ name: "account", type: "address" },
|
|
106354
|
+
{ name: "id", type: "uint256" }
|
|
106355
|
+
],
|
|
106356
|
+
name: "balanceOf",
|
|
106357
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
106358
|
+
stateMutability: "view",
|
|
106359
|
+
type: "function"
|
|
106360
|
+
},
|
|
106361
|
+
{
|
|
106362
|
+
inputs: [{ name: "tokenId", type: "uint256" }],
|
|
106363
|
+
name: "claim",
|
|
106364
|
+
outputs: [],
|
|
106365
|
+
stateMutability: "nonpayable",
|
|
106366
|
+
type: "function"
|
|
106367
|
+
},
|
|
106368
|
+
{
|
|
106369
|
+
inputs: [
|
|
106370
|
+
{ name: "tokenId", type: "uint256" },
|
|
106371
|
+
{ name: "account", type: "address" }
|
|
106372
|
+
],
|
|
106373
|
+
name: "claimable",
|
|
106374
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
106375
|
+
stateMutability: "view",
|
|
106376
|
+
type: "function"
|
|
106377
|
+
}
|
|
106378
|
+
];
|
|
106379
|
+
|
|
106380
|
+
// src/core/services/investment.ts
|
|
106381
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
106382
|
+
var InvestmentService = class extends EventEmitter {
|
|
106383
|
+
constructor(rpcClient, walletService, networkService) {
|
|
106384
|
+
super();
|
|
106385
|
+
this.rpcClient = rpcClient;
|
|
106386
|
+
this.walletService = walletService;
|
|
106387
|
+
this.networkService = networkService;
|
|
106388
|
+
this.chainIdCache = /* @__PURE__ */ new Map();
|
|
106389
|
+
this.erc20Interface = new import_ethers4.Interface(ERC20_ABI2);
|
|
106390
|
+
this.saleInterface = new import_ethers4.Interface(RBT_PRIMARY_SALE_ROUTER_ABI);
|
|
106391
|
+
this.rbtInterface = new import_ethers4.Interface(RBT_PROPERTY_TOKEN_ABI);
|
|
106392
|
+
}
|
|
106393
|
+
assertHexAddress(addr, field) {
|
|
106394
|
+
const a5 = (addr ?? "").trim();
|
|
106395
|
+
if (!a5.startsWith("0x") || a5.length !== 42) {
|
|
106396
|
+
throw new SDKError(`Invalid ${field}`, "INVALID_PARAMS" /* INVALID_PARAMS */);
|
|
106397
|
+
}
|
|
106398
|
+
}
|
|
106399
|
+
toBigInt(v5, field) {
|
|
106400
|
+
try {
|
|
106401
|
+
if (typeof v5 === "bigint") return v5;
|
|
106402
|
+
if (typeof v5 === "number") {
|
|
106403
|
+
if (!Number.isFinite(v5) || v5 < 0) throw new Error("invalid number");
|
|
106404
|
+
return BigInt(v5);
|
|
106405
|
+
}
|
|
106406
|
+
const s5 = (v5 ?? "").toString().trim();
|
|
106407
|
+
if (!s5) throw new Error("empty");
|
|
106408
|
+
return BigInt(s5);
|
|
106409
|
+
} catch {
|
|
106410
|
+
throw new SDKError(`Invalid ${field}`, "INVALID_PARAMS" /* INVALID_PARAMS */);
|
|
106411
|
+
}
|
|
106412
|
+
}
|
|
106413
|
+
/**
|
|
106414
|
+
* Resolve `networkId` (wallet backend blockchainId UUID) or chainId string -> EVM chainId
|
|
106415
|
+
*/
|
|
106416
|
+
async resolveChainId(networkId) {
|
|
106417
|
+
const trimmed = (networkId ?? "").trim();
|
|
106418
|
+
const cached = this.chainIdCache.get(trimmed);
|
|
106419
|
+
if (cached) return cached;
|
|
106420
|
+
const numeric = Number(trimmed);
|
|
106421
|
+
if (!Number.isNaN(numeric) && Number.isFinite(numeric) && numeric > 0) {
|
|
106422
|
+
this.chainIdCache.set(trimmed, numeric);
|
|
106423
|
+
return numeric;
|
|
106424
|
+
}
|
|
106425
|
+
try {
|
|
106426
|
+
const current = await this.networkService.getCurrentNetwork();
|
|
106427
|
+
if (current && current.id === trimmed) {
|
|
106428
|
+
this.chainIdCache.set(trimmed, current.chainId);
|
|
106429
|
+
return current.chainId;
|
|
106430
|
+
}
|
|
106431
|
+
if (current && String(current.chainId) === trimmed) {
|
|
106432
|
+
this.chainIdCache.set(trimmed, current.chainId);
|
|
106433
|
+
return current.chainId;
|
|
106434
|
+
}
|
|
106435
|
+
} catch {
|
|
106436
|
+
}
|
|
106437
|
+
const networks = await this.networkService.getRegisteredNetworks();
|
|
106438
|
+
const found = networks.find((n5) => n5.id === trimmed);
|
|
106439
|
+
if (found) {
|
|
106440
|
+
this.chainIdCache.set(trimmed, found.chainId);
|
|
106441
|
+
return found.chainId;
|
|
106442
|
+
}
|
|
106443
|
+
const foundByChainId = networks.find((n5) => String(n5.chainId) === trimmed);
|
|
106444
|
+
if (foundByChainId) {
|
|
106445
|
+
this.chainIdCache.set(trimmed, foundByChainId.chainId);
|
|
106446
|
+
return foundByChainId.chainId;
|
|
106447
|
+
}
|
|
106448
|
+
throw new SDKError("Invalid network", "INVALID_NETWORK" /* INVALID_NETWORK */);
|
|
106449
|
+
}
|
|
106450
|
+
async ethCall(chainId, to, data) {
|
|
106451
|
+
const res = await this.rpcClient.sendRpc({
|
|
106452
|
+
chainId,
|
|
106453
|
+
method: "eth_call" /* ETH_CALL */,
|
|
106454
|
+
params: [{ to, data }, "latest"]
|
|
106455
|
+
});
|
|
106456
|
+
if (res.error) {
|
|
106457
|
+
throw new SDKError(
|
|
106458
|
+
`ETH_CALL failed: ${res.error.message}`,
|
|
106459
|
+
"REQUEST_FAILED" /* REQUEST_FAILED */,
|
|
106460
|
+
res.error
|
|
106461
|
+
);
|
|
106462
|
+
}
|
|
106463
|
+
if (res.result === void 0) {
|
|
106464
|
+
throw new SDKError(
|
|
106465
|
+
"ETH_CALL returned empty result",
|
|
106466
|
+
"REQUEST_FAILED" /* REQUEST_FAILED */
|
|
106467
|
+
);
|
|
106468
|
+
}
|
|
106469
|
+
return res.result;
|
|
106470
|
+
}
|
|
106471
|
+
decodeU256(resultHex, method) {
|
|
106472
|
+
const decoded = this.erc20Interface.decodeFunctionResult(
|
|
106473
|
+
method,
|
|
106474
|
+
resultHex
|
|
106475
|
+
);
|
|
106476
|
+
return BigInt(decoded[0].toString());
|
|
106477
|
+
}
|
|
106478
|
+
async getOffering(params) {
|
|
106479
|
+
this.assertHexAddress(params.saleRouterAddress, "saleRouterAddress");
|
|
106480
|
+
const chainId = await this.resolveChainId(params.networkId);
|
|
106481
|
+
const offeringId = this.toBigInt(params.offeringId, "offeringId");
|
|
106482
|
+
const data = this.saleInterface.encodeFunctionData("offerings", [
|
|
106483
|
+
offeringId
|
|
106484
|
+
]);
|
|
106485
|
+
const result = await this.ethCall(chainId, params.saleRouterAddress, data);
|
|
106486
|
+
const decoded = this.saleInterface.decodeFunctionResult("offerings", result);
|
|
106487
|
+
const asset = decoded[0];
|
|
106488
|
+
const seriesId = BigInt(decoded[1].toString());
|
|
106489
|
+
const unitPrice = BigInt(decoded[2].toString());
|
|
106490
|
+
const remainingUnits = BigInt(decoded[3].toString());
|
|
106491
|
+
const startAt = BigInt(decoded[4].toString());
|
|
106492
|
+
const endAt = BigInt(decoded[5].toString());
|
|
106493
|
+
const treasury = decoded[6];
|
|
106494
|
+
const enabled = Boolean(decoded[7]);
|
|
106495
|
+
return {
|
|
106496
|
+
asset,
|
|
106497
|
+
seriesId,
|
|
106498
|
+
unitPrice,
|
|
106499
|
+
remainingUnits,
|
|
106500
|
+
startAt,
|
|
106501
|
+
endAt,
|
|
106502
|
+
treasury,
|
|
106503
|
+
enabled
|
|
106504
|
+
};
|
|
106505
|
+
}
|
|
106506
|
+
/**
|
|
106507
|
+
* USDR로 투자 (approve 필요. autoApprove 옵션 제공)
|
|
106508
|
+
* - Router.buy(offeringId, units, maxCost) 호출
|
|
106509
|
+
*/
|
|
106510
|
+
async investRbtWithUsdr(params) {
|
|
106511
|
+
this.assertHexAddress(params.usdrAddress, "usdrAddress");
|
|
106512
|
+
this.assertHexAddress(params.saleRouterAddress, "saleRouterAddress");
|
|
106513
|
+
const chainId = await this.resolveChainId(params.networkId);
|
|
106514
|
+
const offeringId = this.toBigInt(params.offeringId, "offeringId");
|
|
106515
|
+
const units = this.toBigInt(params.units, "units");
|
|
106516
|
+
if (units <= 0n) {
|
|
106517
|
+
throw new SDKError("Invalid units", "INVALID_PARAMS" /* INVALID_PARAMS */);
|
|
106518
|
+
}
|
|
106519
|
+
const offering = await this.getOffering({
|
|
106520
|
+
networkId: params.networkId,
|
|
106521
|
+
saleRouterAddress: params.saleRouterAddress,
|
|
106522
|
+
offeringId
|
|
106523
|
+
});
|
|
106524
|
+
if (!offering.enabled) {
|
|
106525
|
+
throw new SDKError("Offering is disabled", "REQUEST_FAILED" /* REQUEST_FAILED */);
|
|
106526
|
+
}
|
|
106527
|
+
const cost = units * offering.unitPrice;
|
|
106528
|
+
const maxCost = params.maxCostWei != null ? this.toBigInt(params.maxCostWei, "maxCostWei") : cost;
|
|
106529
|
+
if (maxCost < cost) {
|
|
106530
|
+
throw new SDKError(
|
|
106531
|
+
"maxCostWei is less than required cost",
|
|
106532
|
+
"INVALID_PARAMS" /* INVALID_PARAMS */
|
|
106533
|
+
);
|
|
106534
|
+
}
|
|
106535
|
+
const buyer = await this.walletService.getAddress();
|
|
106536
|
+
let approvalTxHash;
|
|
106537
|
+
const autoApprove = params.autoApprove ?? true;
|
|
106538
|
+
const approveMax = params.approveMax ?? true;
|
|
106539
|
+
const waitForApprovalReceipt = params.waitForApprovalReceipt ?? true;
|
|
106540
|
+
if (autoApprove) {
|
|
106541
|
+
const allowanceData = this.erc20Interface.encodeFunctionData(
|
|
106542
|
+
"allowance",
|
|
106543
|
+
[buyer, params.saleRouterAddress]
|
|
106544
|
+
);
|
|
106545
|
+
const allowanceHex = await this.ethCall(
|
|
106546
|
+
chainId,
|
|
106547
|
+
params.usdrAddress,
|
|
106548
|
+
allowanceData
|
|
106549
|
+
);
|
|
106550
|
+
const allowanceDecoded = this.erc20Interface.decodeFunctionResult(
|
|
106551
|
+
"allowance",
|
|
106552
|
+
allowanceHex
|
|
106553
|
+
);
|
|
106554
|
+
const allowance = BigInt(allowanceDecoded[0].toString());
|
|
106555
|
+
if (allowance < cost) {
|
|
106556
|
+
const approveAmount = approveMax ? MAX_UINT256 : cost;
|
|
106557
|
+
const approveData = this.erc20Interface.encodeFunctionData("approve", [
|
|
106558
|
+
params.saleRouterAddress,
|
|
106559
|
+
approveAmount.toString()
|
|
106560
|
+
]);
|
|
106561
|
+
approvalTxHash = await this.walletService.sendTransaction({
|
|
106562
|
+
to: params.usdrAddress,
|
|
106563
|
+
value: "0",
|
|
106564
|
+
data: approveData,
|
|
106565
|
+
chainId,
|
|
106566
|
+
gasLimit: params.gasLimitApprove
|
|
106567
|
+
});
|
|
106568
|
+
this.trackTransaction(approvalTxHash, chainId);
|
|
106569
|
+
if (waitForApprovalReceipt) {
|
|
106570
|
+
const ok = await this.waitForSuccessReceipt(approvalTxHash, chainId);
|
|
106571
|
+
if (!ok) {
|
|
106572
|
+
throw new SDKError(
|
|
106573
|
+
"Approve transaction failed",
|
|
106574
|
+
"TRANSACTION_FAILED" /* TRANSACTION_FAILED */
|
|
106575
|
+
);
|
|
106576
|
+
}
|
|
106577
|
+
}
|
|
106578
|
+
}
|
|
106579
|
+
}
|
|
106580
|
+
const buyData = this.saleInterface.encodeFunctionData("buy", [
|
|
106581
|
+
offeringId,
|
|
106582
|
+
units,
|
|
106583
|
+
maxCost
|
|
106584
|
+
]);
|
|
106585
|
+
const purchaseTxHash = await this.walletService.sendTransaction({
|
|
106586
|
+
to: params.saleRouterAddress,
|
|
106587
|
+
value: "0",
|
|
106588
|
+
data: buyData,
|
|
106589
|
+
chainId,
|
|
106590
|
+
gasLimit: params.gasLimitBuy
|
|
106591
|
+
});
|
|
106592
|
+
this.trackTransaction(purchaseTxHash, chainId);
|
|
106593
|
+
return {
|
|
106594
|
+
offering,
|
|
106595
|
+
costWei: cost.toString(),
|
|
106596
|
+
approvalTxHash,
|
|
106597
|
+
purchaseTxHash
|
|
106598
|
+
};
|
|
106599
|
+
}
|
|
106600
|
+
/**
|
|
106601
|
+
* RBT 수익(이자) claim
|
|
106602
|
+
* - RBTPropertyToken.claim(seriesId)
|
|
106603
|
+
*/
|
|
106604
|
+
async claimRbtRevenue(params) {
|
|
106605
|
+
this.assertHexAddress(params.rbtAssetAddress, "rbtAssetAddress");
|
|
106606
|
+
const chainId = await this.resolveChainId(params.networkId);
|
|
106607
|
+
const seriesId = this.toBigInt(params.seriesId, "seriesId");
|
|
106608
|
+
const claimData = this.rbtInterface.encodeFunctionData("claim", [seriesId]);
|
|
106609
|
+
const txHash = await this.walletService.sendTransaction({
|
|
106610
|
+
to: params.rbtAssetAddress,
|
|
106611
|
+
value: "0",
|
|
106612
|
+
data: claimData,
|
|
106613
|
+
chainId,
|
|
106614
|
+
gasLimit: params.gasLimit
|
|
106615
|
+
});
|
|
106616
|
+
this.trackTransaction(txHash, chainId);
|
|
106617
|
+
return { txHash };
|
|
106618
|
+
}
|
|
106619
|
+
/**
|
|
106620
|
+
* claimable 조회 (eth_call)
|
|
106621
|
+
*/
|
|
106622
|
+
async getClaimable(params) {
|
|
106623
|
+
this.assertHexAddress(params.rbtAssetAddress, "rbtAssetAddress");
|
|
106624
|
+
const chainId = await this.resolveChainId(params.networkId);
|
|
106625
|
+
const seriesId = this.toBigInt(params.seriesId, "seriesId");
|
|
106626
|
+
const account = params.account ?? await this.walletService.getAddress();
|
|
106627
|
+
this.assertHexAddress(account, "account");
|
|
106628
|
+
const data = this.rbtInterface.encodeFunctionData("claimable", [
|
|
106629
|
+
seriesId,
|
|
106630
|
+
account
|
|
106631
|
+
]);
|
|
106632
|
+
const result = await this.ethCall(chainId, params.rbtAssetAddress, data);
|
|
106633
|
+
const decoded = this.rbtInterface.decodeFunctionResult("claimable", result);
|
|
106634
|
+
return BigInt(decoded[0].toString()).toString();
|
|
106635
|
+
}
|
|
106636
|
+
/**
|
|
106637
|
+
* RBT balanceOf 조회 (eth_call)
|
|
106638
|
+
*/
|
|
106639
|
+
async getRbtBalance(params) {
|
|
106640
|
+
this.assertHexAddress(params.rbtAssetAddress, "rbtAssetAddress");
|
|
106641
|
+
const chainId = await this.resolveChainId(params.networkId);
|
|
106642
|
+
const seriesId = this.toBigInt(params.seriesId, "seriesId");
|
|
106643
|
+
const account = params.account ?? await this.walletService.getAddress();
|
|
106644
|
+
this.assertHexAddress(account, "account");
|
|
106645
|
+
const data = this.rbtInterface.encodeFunctionData("balanceOf", [
|
|
106646
|
+
account,
|
|
106647
|
+
seriesId
|
|
106648
|
+
]);
|
|
106649
|
+
const result = await this.ethCall(chainId, params.rbtAssetAddress, data);
|
|
106650
|
+
const decoded = this.rbtInterface.decodeFunctionResult("balanceOf", result);
|
|
106651
|
+
return BigInt(decoded[0].toString()).toString();
|
|
106652
|
+
}
|
|
106653
|
+
async waitForSuccessReceipt(txHash, chainId) {
|
|
106654
|
+
let retryCount = 0;
|
|
106655
|
+
const MAX_RETRIES = 20;
|
|
106656
|
+
while (retryCount < MAX_RETRIES) {
|
|
106657
|
+
const res = await this.rpcClient.sendRpc({
|
|
106658
|
+
chainId,
|
|
106659
|
+
method: "eth_getTransactionReceipt" /* ETH_GET_TRANSACTION_RECEIPT */,
|
|
106660
|
+
params: [txHash]
|
|
106661
|
+
});
|
|
106662
|
+
if (res.result) {
|
|
106663
|
+
return res.result.status === "0x1";
|
|
106664
|
+
}
|
|
106665
|
+
retryCount++;
|
|
106666
|
+
await new Promise((r5) => setTimeout$1(r5, 3e3));
|
|
106667
|
+
}
|
|
106668
|
+
return false;
|
|
106669
|
+
}
|
|
106670
|
+
trackTransaction(txHash, chainId) {
|
|
106671
|
+
let retryCount = 0;
|
|
106672
|
+
const MAX_RETRIES = 20;
|
|
106673
|
+
const checkStatus = async () => {
|
|
106674
|
+
try {
|
|
106675
|
+
const response = await this.rpcClient.sendRpc({
|
|
106676
|
+
chainId,
|
|
106677
|
+
method: "eth_getTransactionReceipt" /* ETH_GET_TRANSACTION_RECEIPT */,
|
|
106678
|
+
params: [txHash]
|
|
106679
|
+
});
|
|
106680
|
+
if (response.result) {
|
|
106681
|
+
const status = response.result.status === "0x1" ? "SUCCESS" /* SUCCESS */ : "FAILED" /* FAILED */;
|
|
106682
|
+
this.emit("transactionStatusChanged", {
|
|
106683
|
+
hash: txHash,
|
|
106684
|
+
status,
|
|
106685
|
+
timestamp: Date.now()
|
|
106686
|
+
});
|
|
106687
|
+
return;
|
|
106688
|
+
}
|
|
106689
|
+
retryCount++;
|
|
106690
|
+
if (retryCount < MAX_RETRIES) {
|
|
106691
|
+
setTimeout$1(checkStatus, 3e3);
|
|
106692
|
+
} else {
|
|
106693
|
+
this.emit("transactionStatusChanged", {
|
|
106694
|
+
hash: txHash,
|
|
106695
|
+
status: "FAILED" /* FAILED */,
|
|
106696
|
+
timestamp: Date.now(),
|
|
106697
|
+
error: "Transaction timeout"
|
|
106698
|
+
});
|
|
106699
|
+
}
|
|
106700
|
+
} catch (error) {
|
|
106701
|
+
this.emit("transactionStatusChanged", {
|
|
106702
|
+
hash: txHash,
|
|
106703
|
+
status: "FAILED" /* FAILED */,
|
|
106704
|
+
timestamp: Date.now(),
|
|
106705
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
106706
|
+
});
|
|
106707
|
+
}
|
|
106708
|
+
};
|
|
106709
|
+
checkStatus();
|
|
106710
|
+
}
|
|
106711
|
+
};
|
|
106712
|
+
|
|
106335
106713
|
// src/core/internal.ts
|
|
106336
106714
|
var InternalCoreImpl = class {
|
|
106337
106715
|
constructor(options) {
|
|
@@ -106373,16 +106751,7 @@ var InternalCoreImpl = class {
|
|
|
106373
106751
|
getTokenBalance: (params) => this.assetService.getTokenBalance(params),
|
|
106374
106752
|
approveToken: (params) => this.assetService.approveToken(params),
|
|
106375
106753
|
getAllowance: (params) => this.assetService.getAllowance(params),
|
|
106376
|
-
// getTokenInfo: (params: TokenInfoParams) =>
|
|
106377
|
-
// this.assetService.getTokenInfo(params),
|
|
106378
106754
|
addNFTCollection: (params) => this.assetService.addNFTCollection(params),
|
|
106379
|
-
// checkSecurityTokenCompliance: (params: {
|
|
106380
|
-
// networkId: string
|
|
106381
|
-
// tokenAddress: string
|
|
106382
|
-
// from: string
|
|
106383
|
-
// to: string
|
|
106384
|
-
// amount: string
|
|
106385
|
-
// }) => this.assetService.checkSecurityTokenCompliance(params),
|
|
106386
106755
|
on: (event, listener) => this.assetService.on(event, listener),
|
|
106387
106756
|
off: (event, listener) => this.assetService.off(event, listener),
|
|
106388
106757
|
getTokenInfo: (params) => this.assetService.getTokenInfo(params),
|
|
@@ -106390,6 +106759,15 @@ var InternalCoreImpl = class {
|
|
|
106390
106759
|
getTokenFullInfo: (params) => this.assetService.getTokenFullInfo(params),
|
|
106391
106760
|
getRegisteredCoins: (networkId) => this.assetService.getRegisteredCoins(networkId)
|
|
106392
106761
|
};
|
|
106762
|
+
this.investment = {
|
|
106763
|
+
getOffering: (params) => this.investmentService.getOffering(params),
|
|
106764
|
+
investRbtWithUsdr: (params) => this.investmentService.investRbtWithUsdr(params),
|
|
106765
|
+
claimRbtRevenue: (params) => this.investmentService.claimRbtRevenue(params),
|
|
106766
|
+
getClaimable: (params) => this.investmentService.getClaimable(params),
|
|
106767
|
+
getRbtBalance: (params) => this.investmentService.getRbtBalance(params),
|
|
106768
|
+
on: (event, listener) => this.investmentService.on(event, listener),
|
|
106769
|
+
off: (event, listener) => this.investmentService.off(event, listener)
|
|
106770
|
+
};
|
|
106393
106771
|
const httpClient = new HttpClient(options);
|
|
106394
106772
|
const firebase = new FirebaseAuth(options);
|
|
106395
106773
|
const userClient = new UserClient(httpClient);
|
|
@@ -106415,6 +106793,11 @@ var InternalCoreImpl = class {
|
|
|
106415
106793
|
userClient,
|
|
106416
106794
|
options.orgHost
|
|
106417
106795
|
);
|
|
106796
|
+
this.investmentService = new InvestmentService(
|
|
106797
|
+
rpcClient,
|
|
106798
|
+
this.walletService,
|
|
106799
|
+
this.networkService
|
|
106800
|
+
);
|
|
106418
106801
|
}
|
|
106419
106802
|
};
|
|
106420
106803
|
|
|
@@ -106690,6 +107073,35 @@ var AssetModule = class {
|
|
|
106690
107073
|
}
|
|
106691
107074
|
};
|
|
106692
107075
|
|
|
107076
|
+
// src/modules/Investment.ts
|
|
107077
|
+
var InvestmentModule = class {
|
|
107078
|
+
constructor(options, core) {
|
|
107079
|
+
this.options = options;
|
|
107080
|
+
this.core = core;
|
|
107081
|
+
}
|
|
107082
|
+
getOffering(params) {
|
|
107083
|
+
return this.core.investment.getOffering(params);
|
|
107084
|
+
}
|
|
107085
|
+
investRbtWithUsdr(params) {
|
|
107086
|
+
return this.core.investment.investRbtWithUsdr(params);
|
|
107087
|
+
}
|
|
107088
|
+
claimRbtRevenue(params) {
|
|
107089
|
+
return this.core.investment.claimRbtRevenue(params);
|
|
107090
|
+
}
|
|
107091
|
+
getClaimable(params) {
|
|
107092
|
+
return this.core.investment.getClaimable(params);
|
|
107093
|
+
}
|
|
107094
|
+
getRbtBalance(params) {
|
|
107095
|
+
return this.core.investment.getRbtBalance(params);
|
|
107096
|
+
}
|
|
107097
|
+
on(event, listener) {
|
|
107098
|
+
this.core.investment.on(event, listener);
|
|
107099
|
+
}
|
|
107100
|
+
off(event, listener) {
|
|
107101
|
+
this.core.investment.off(event, listener);
|
|
107102
|
+
}
|
|
107103
|
+
};
|
|
107104
|
+
|
|
106693
107105
|
// src/utils/network.ts
|
|
106694
107106
|
var KNOWN_NETWORKS = {
|
|
106695
107107
|
1: {
|
|
@@ -106757,92 +107169,178 @@ var WeBlockSDK = class {
|
|
|
106757
107169
|
this.initialized = false;
|
|
106758
107170
|
this.user = {
|
|
106759
107171
|
signIn: async (provider) => {
|
|
107172
|
+
this.ensureInitialized();
|
|
106760
107173
|
return this.userModule.signIn(provider);
|
|
106761
107174
|
},
|
|
106762
107175
|
createWallet: async (password) => {
|
|
107176
|
+
this.ensureInitialized();
|
|
106763
107177
|
return this.userModule.createWallet(password);
|
|
106764
107178
|
},
|
|
106765
107179
|
retrieveWallet: async (password) => {
|
|
107180
|
+
this.ensureInitialized();
|
|
106766
107181
|
return this.userModule.retrieveWallet(password);
|
|
106767
107182
|
},
|
|
106768
107183
|
/**
|
|
106769
107184
|
* ✅ 추가: PIN reset API 노출
|
|
106770
107185
|
*/
|
|
106771
107186
|
resetPin: async (newPassword) => {
|
|
107187
|
+
this.ensureInitialized();
|
|
106772
107188
|
return this.userModule.resetPin(newPassword);
|
|
106773
107189
|
},
|
|
106774
107190
|
signOut: async () => {
|
|
107191
|
+
this.ensureInitialized();
|
|
106775
107192
|
return this.userModule.signOut();
|
|
106776
107193
|
}
|
|
106777
107194
|
};
|
|
106778
107195
|
this.wallet = {
|
|
106779
107196
|
getInfo: async () => {
|
|
107197
|
+
this.ensureInitialized();
|
|
106780
107198
|
return this.walletModule.getInfo();
|
|
106781
107199
|
},
|
|
106782
107200
|
onWalletUpdate: (callback) => {
|
|
107201
|
+
this.ensureInitialized();
|
|
106783
107202
|
return this.walletModule.onWalletUpdate(callback);
|
|
106784
107203
|
},
|
|
106785
107204
|
onTransactionUpdate: (callback) => {
|
|
107205
|
+
this.ensureInitialized();
|
|
106786
107206
|
return this.walletModule.onTransactionUpdate(callback);
|
|
106787
107207
|
},
|
|
106788
107208
|
getBalance: (address, chainId) => {
|
|
107209
|
+
this.ensureInitialized();
|
|
106789
107210
|
return this.walletModule.getBalance(address, chainId);
|
|
106790
107211
|
},
|
|
106791
107212
|
getTransactionCount: (address, chainId) => {
|
|
107213
|
+
this.ensureInitialized();
|
|
106792
107214
|
return this.walletModule.getTransactionCount(address, chainId);
|
|
106793
107215
|
},
|
|
106794
107216
|
getBlockNumber: (chainId) => {
|
|
107217
|
+
this.ensureInitialized();
|
|
106795
107218
|
return this.walletModule.getBlockNumber(chainId);
|
|
106796
107219
|
},
|
|
106797
107220
|
sendRawTransaction: (signedTx, chainId) => {
|
|
107221
|
+
this.ensureInitialized();
|
|
106798
107222
|
return this.walletModule.sendRawTransaction(signedTx, chainId);
|
|
106799
107223
|
},
|
|
106800
107224
|
getTransactionReceipt: (txHash, chainId) => {
|
|
107225
|
+
this.ensureInitialized();
|
|
106801
107226
|
return this.walletModule.getTransactionReceipt(txHash, chainId);
|
|
106802
107227
|
},
|
|
106803
107228
|
getTransaction: (txHash, chainId) => {
|
|
107229
|
+
this.ensureInitialized();
|
|
106804
107230
|
return this.walletModule.getTransaction(txHash, chainId);
|
|
106805
107231
|
},
|
|
106806
107232
|
estimateGas: (txParams, chainId) => {
|
|
107233
|
+
this.ensureInitialized();
|
|
106807
107234
|
return this.walletModule.estimateGas(txParams, chainId);
|
|
106808
107235
|
},
|
|
106809
107236
|
getGasPrice: (chainId) => {
|
|
107237
|
+
this.ensureInitialized();
|
|
106810
107238
|
return this.walletModule.getGasPrice(chainId);
|
|
106811
107239
|
},
|
|
106812
107240
|
call: (txParams, blockParam, chainId) => {
|
|
107241
|
+
this.ensureInitialized();
|
|
106813
107242
|
return this.walletModule.call(txParams, blockParam, chainId);
|
|
106814
107243
|
}
|
|
106815
107244
|
};
|
|
106816
107245
|
this.network = {
|
|
106817
|
-
getAvailableNetworks: () =>
|
|
106818
|
-
|
|
106819
|
-
|
|
106820
|
-
|
|
107246
|
+
getAvailableNetworks: () => {
|
|
107247
|
+
this.ensureInitialized();
|
|
107248
|
+
return this.networkModule.getAvailableNetworks();
|
|
107249
|
+
},
|
|
107250
|
+
addNetwork: (request) => {
|
|
107251
|
+
this.ensureInitialized();
|
|
107252
|
+
return this.networkModule.addNetwork(request);
|
|
107253
|
+
},
|
|
107254
|
+
switchNetwork: (networkId) => {
|
|
107255
|
+
this.ensureInitialized();
|
|
107256
|
+
return this.networkModule.switchNetwork(networkId);
|
|
107257
|
+
},
|
|
107258
|
+
getCurrentNetwork: () => {
|
|
107259
|
+
this.ensureInitialized();
|
|
107260
|
+
return this.networkModule.getCurrentNetwork();
|
|
107261
|
+
}
|
|
106821
107262
|
};
|
|
106822
107263
|
this.asset = {
|
|
106823
107264
|
transfer: async (params) => {
|
|
107265
|
+
this.ensureInitialized();
|
|
106824
107266
|
return this.assetModule.transfer(params);
|
|
106825
107267
|
},
|
|
106826
107268
|
addToken: async (params) => {
|
|
107269
|
+
this.ensureInitialized();
|
|
106827
107270
|
return this.assetModule.addToken(params);
|
|
106828
107271
|
},
|
|
106829
107272
|
addNFTCollection: async (params) => {
|
|
107273
|
+
this.ensureInitialized();
|
|
106830
107274
|
return this.assetModule.addNFTCollection(params);
|
|
106831
107275
|
},
|
|
106832
107276
|
on: (event, listener) => {
|
|
107277
|
+
this.ensureInitialized();
|
|
106833
107278
|
this.assetModule.on(event, listener);
|
|
106834
107279
|
},
|
|
106835
107280
|
off: (event, listener) => {
|
|
107281
|
+
this.ensureInitialized();
|
|
106836
107282
|
this.assetModule.off(event, listener);
|
|
106837
107283
|
},
|
|
106838
107284
|
getTokenInfo: async (params) => {
|
|
107285
|
+
this.ensureInitialized();
|
|
106839
107286
|
return this.assetModule.getTokenInfo(params);
|
|
106840
107287
|
},
|
|
106841
107288
|
registerToken: async (params) => {
|
|
107289
|
+
this.ensureInitialized();
|
|
106842
107290
|
return this.assetModule.registerToken(params);
|
|
106843
107291
|
},
|
|
106844
107292
|
getTokenFullInfo: async (params) => {
|
|
107293
|
+
this.ensureInitialized();
|
|
106845
107294
|
return this.assetModule.getTokenFullInfo(params);
|
|
107295
|
+
},
|
|
107296
|
+
/**
|
|
107297
|
+
* ✅ ERC20 잔액 조회 (주의: 현재 AssetModule 구현은 raw balance string을 반환)
|
|
107298
|
+
* - TokenBalance(객체)가 아니라 string(wei) 입니다.
|
|
107299
|
+
*/
|
|
107300
|
+
getTokenBalance: async (params) => {
|
|
107301
|
+
this.ensureInitialized();
|
|
107302
|
+
return this.assetModule.getTokenBalance(params);
|
|
107303
|
+
},
|
|
107304
|
+
approveToken: async (params) => {
|
|
107305
|
+
this.ensureInitialized();
|
|
107306
|
+
return this.assetModule.approveToken(params);
|
|
107307
|
+
},
|
|
107308
|
+
getAllowance: async (params) => {
|
|
107309
|
+
this.ensureInitialized();
|
|
107310
|
+
return this.assetModule.getAllowance(params);
|
|
107311
|
+
}
|
|
107312
|
+
};
|
|
107313
|
+
/**
|
|
107314
|
+
* ✅ NEW: Investment API Surface
|
|
107315
|
+
*/
|
|
107316
|
+
this.invest = {
|
|
107317
|
+
getOffering: async (params) => {
|
|
107318
|
+
this.ensureInitialized();
|
|
107319
|
+
return this.investmentModule.getOffering(params);
|
|
107320
|
+
},
|
|
107321
|
+
investRbtWithUsdr: async (params) => {
|
|
107322
|
+
this.ensureInitialized();
|
|
107323
|
+
return this.investmentModule.investRbtWithUsdr(params);
|
|
107324
|
+
},
|
|
107325
|
+
claimRbtRevenue: async (params) => {
|
|
107326
|
+
this.ensureInitialized();
|
|
107327
|
+
return this.investmentModule.claimRbtRevenue(params);
|
|
107328
|
+
},
|
|
107329
|
+
getClaimable: async (params) => {
|
|
107330
|
+
this.ensureInitialized();
|
|
107331
|
+
return this.investmentModule.getClaimable(params);
|
|
107332
|
+
},
|
|
107333
|
+
getRbtBalance: async (params) => {
|
|
107334
|
+
this.ensureInitialized();
|
|
107335
|
+
return this.investmentModule.getRbtBalance(params);
|
|
107336
|
+
},
|
|
107337
|
+
on: (event, listener) => {
|
|
107338
|
+
this.ensureInitialized();
|
|
107339
|
+
this.investmentModule.on(event, listener);
|
|
107340
|
+
},
|
|
107341
|
+
off: (event, listener) => {
|
|
107342
|
+
this.ensureInitialized();
|
|
107343
|
+
this.investmentModule.off(event, listener);
|
|
106846
107344
|
}
|
|
106847
107345
|
};
|
|
106848
107346
|
this.validateOptions(options);
|
|
@@ -106852,6 +107350,7 @@ var WeBlockSDK = class {
|
|
|
106852
107350
|
this.userModule = new UserModule(options, internalCore, this.walletModule);
|
|
106853
107351
|
this.assetModule = new AssetModule(options, internalCore);
|
|
106854
107352
|
this.networkModule = new NetworkModule(options, internalCore);
|
|
107353
|
+
this.investmentModule = new InvestmentModule(options, internalCore);
|
|
106855
107354
|
this.initialized = true;
|
|
106856
107355
|
console.info("WeBlock SDK initialized successfully");
|
|
106857
107356
|
}
|
|
@@ -106860,13 +107359,15 @@ var WeBlockSDK = class {
|
|
|
106860
107359
|
if (!["local", "dev", "stage", "prod"].includes(environment)) {
|
|
106861
107360
|
throw new SDKError("Invalid environment", "INVALID_CONFIG" /* INVALID_CONFIG */);
|
|
106862
107361
|
}
|
|
106863
|
-
if (!apiKey)
|
|
107362
|
+
if (!apiKey) {
|
|
106864
107363
|
throw new SDKError("API key is required", "INVALID_CONFIG" /* INVALID_CONFIG */);
|
|
106865
|
-
|
|
107364
|
+
}
|
|
107365
|
+
if (!orgHost) {
|
|
106866
107366
|
throw new SDKError(
|
|
106867
107367
|
"Organization host is required",
|
|
106868
107368
|
"INVALID_CONFIG" /* INVALID_CONFIG */
|
|
106869
107369
|
);
|
|
107370
|
+
}
|
|
106870
107371
|
}
|
|
106871
107372
|
ensureInitialized() {
|
|
106872
107373
|
if (!this.initialized) {
|