@sequence0/sdk 1.1.0 → 1.2.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/README.md +1 -1
- package/dist/chains/algorand.d.ts +44 -0
- package/dist/chains/algorand.d.ts.map +1 -0
- package/dist/chains/algorand.js +148 -0
- package/dist/chains/algorand.js.map +1 -0
- package/dist/chains/aptos.d.ts +39 -0
- package/dist/chains/aptos.d.ts.map +1 -0
- package/dist/chains/aptos.js +168 -0
- package/dist/chains/aptos.js.map +1 -0
- package/dist/chains/bitcoin-taproot.d.ts +77 -14
- package/dist/chains/bitcoin-taproot.d.ts.map +1 -1
- package/dist/chains/bitcoin-taproot.js +324 -65
- package/dist/chains/bitcoin-taproot.js.map +1 -1
- package/dist/chains/bitcoin.d.ts +12 -7
- package/dist/chains/bitcoin.d.ts.map +1 -1
- package/dist/chains/bitcoin.js +14 -9
- package/dist/chains/bitcoin.js.map +1 -1
- package/dist/chains/cardano.d.ts +42 -0
- package/dist/chains/cardano.d.ts.map +1 -0
- package/dist/chains/cardano.js +188 -0
- package/dist/chains/cardano.js.map +1 -0
- package/dist/chains/cosmos.d.ts +42 -0
- package/dist/chains/cosmos.d.ts.map +1 -0
- package/dist/chains/cosmos.js +216 -0
- package/dist/chains/cosmos.js.map +1 -0
- package/dist/chains/dogecoin-litecoin.d.ts +57 -0
- package/dist/chains/dogecoin-litecoin.d.ts.map +1 -0
- package/dist/chains/dogecoin-litecoin.js +521 -0
- package/dist/chains/dogecoin-litecoin.js.map +1 -0
- package/dist/chains/ethereum.d.ts.map +1 -1
- package/dist/chains/ethereum.js +16 -0
- package/dist/chains/ethereum.js.map +1 -1
- package/dist/chains/hedera.d.ts +113 -0
- package/dist/chains/hedera.d.ts.map +1 -0
- package/dist/chains/hedera.js +302 -0
- package/dist/chains/hedera.js.map +1 -0
- package/dist/chains/icp.d.ts +95 -0
- package/dist/chains/icp.d.ts.map +1 -0
- package/dist/chains/icp.js +520 -0
- package/dist/chains/icp.js.map +1 -0
- package/dist/chains/kaspa.d.ts +152 -0
- package/dist/chains/kaspa.d.ts.map +1 -0
- package/dist/chains/kaspa.js +790 -0
- package/dist/chains/kaspa.js.map +1 -0
- package/dist/chains/multiversx.d.ts +143 -0
- package/dist/chains/multiversx.d.ts.map +1 -0
- package/dist/chains/multiversx.js +524 -0
- package/dist/chains/multiversx.js.map +1 -0
- package/dist/chains/near.d.ts +40 -0
- package/dist/chains/near.d.ts.map +1 -0
- package/dist/chains/near.js +170 -0
- package/dist/chains/near.js.map +1 -0
- package/dist/chains/polkadot.d.ts +43 -0
- package/dist/chains/polkadot.d.ts.map +1 -0
- package/dist/chains/polkadot.js +179 -0
- package/dist/chains/polkadot.js.map +1 -0
- package/dist/chains/ripple.d.ts +41 -0
- package/dist/chains/ripple.d.ts.map +1 -0
- package/dist/chains/ripple.js +190 -0
- package/dist/chains/ripple.js.map +1 -0
- package/dist/chains/stellar.d.ts +40 -0
- package/dist/chains/stellar.d.ts.map +1 -0
- package/dist/chains/stellar.js +156 -0
- package/dist/chains/stellar.js.map +1 -0
- package/dist/chains/sui.d.ts +44 -0
- package/dist/chains/sui.d.ts.map +1 -0
- package/dist/chains/sui.js +157 -0
- package/dist/chains/sui.js.map +1 -0
- package/dist/chains/tezos.d.ts +43 -0
- package/dist/chains/tezos.d.ts.map +1 -0
- package/dist/chains/tezos.js +162 -0
- package/dist/chains/tezos.js.map +1 -0
- package/dist/chains/ton.d.ts +40 -0
- package/dist/chains/ton.d.ts.map +1 -0
- package/dist/chains/ton.js +168 -0
- package/dist/chains/ton.js.map +1 -0
- package/dist/chains/tron.d.ts +41 -0
- package/dist/chains/tron.d.ts.map +1 -0
- package/dist/chains/tron.js +124 -0
- package/dist/chains/tron.js.map +1 -0
- package/dist/core/client.d.ts +4 -5
- package/dist/core/client.d.ts.map +1 -1
- package/dist/core/client.js +54 -29
- package/dist/core/client.js.map +1 -1
- package/dist/core/types.d.ts +161 -1
- package/dist/core/types.d.ts.map +1 -1
- package/dist/erc4337/types.js +2 -2
- package/dist/index.d.ts +21 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +85 -4
- package/dist/index.js.map +1 -1
- package/dist/utils/discovery.d.ts.map +1 -1
- package/dist/utils/discovery.js +56 -1
- package/dist/utils/discovery.js.map +1 -1
- package/dist/utils/eip712.d.ts +36 -0
- package/dist/utils/eip712.d.ts.map +1 -0
- package/dist/utils/eip712.js +80 -0
- package/dist/utils/eip712.js.map +1 -0
- package/dist/utils/fee.d.ts +2 -2
- package/dist/utils/fee.js +2 -2
- package/dist/utils/optional-deps.d.ts +9 -0
- package/dist/utils/optional-deps.d.ts.map +1 -0
- package/dist/utils/optional-deps.js +21 -0
- package/dist/utils/optional-deps.js.map +1 -0
- package/dist/utils/validation.d.ts +8 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +24 -1
- package/dist/utils/validation.js.map +1 -1
- package/dist/utils/websocket.js +1 -1
- package/dist/utils/websocket.js.map +1 -1
- package/dist/wallet/wallet.d.ts +16 -2
- package/dist/wallet/wallet.d.ts.map +1 -1
- package/dist/wallet/wallet.js +131 -58
- package/dist/wallet/wallet.js.map +1 -1
- package/package.json +35 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TON Chain Adapter
|
|
3
|
+
*
|
|
4
|
+
* Builds TON blockchain transactions using Cell/BoC serialization,
|
|
5
|
+
* attaches Ed25519 signatures from the FROST threshold signing
|
|
6
|
+
* network, and broadcasts via TON Center API.
|
|
7
|
+
*
|
|
8
|
+
* Requires: npm install @ton/ton
|
|
9
|
+
*/
|
|
10
|
+
import { ChainAdapter, TonTransaction } from '../core/types';
|
|
11
|
+
export declare class TonAdapter implements ChainAdapter {
|
|
12
|
+
private rpcUrl;
|
|
13
|
+
private network;
|
|
14
|
+
private tonSdk;
|
|
15
|
+
constructor(network?: 'mainnet' | 'testnet', rpcUrl?: string);
|
|
16
|
+
getRpcUrl(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Build an unsigned TON transaction.
|
|
19
|
+
*
|
|
20
|
+
* TON uses Cell tree serialization. The signing payload is the
|
|
21
|
+
* SHA-256 hash of the external message body cell.
|
|
22
|
+
*/
|
|
23
|
+
buildTransaction(tx: TonTransaction, fromAddress: string): Promise<string>;
|
|
24
|
+
getSigningPayload(unsignedTx: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Attach an Ed25519 signature to the TON transaction
|
|
27
|
+
*/
|
|
28
|
+
attachSignature(unsignedTx: string, signature: string): Promise<string>;
|
|
29
|
+
/**
|
|
30
|
+
* Broadcast a signed TON transaction
|
|
31
|
+
*/
|
|
32
|
+
broadcast(signedTx: string): Promise<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Get TON balance in nanotons
|
|
35
|
+
*/
|
|
36
|
+
getBalance(address: string): Promise<string>;
|
|
37
|
+
}
|
|
38
|
+
export declare function createTonAdapter(rpcUrl?: string): TonAdapter;
|
|
39
|
+
export declare function createTonTestnetAdapter(rpcUrl?: string): TonAdapter;
|
|
40
|
+
//# sourceMappingURL=ton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ton.d.ts","sourceRoot":"","sources":["../../src/chains/ton.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAS7D,qBAAa,UAAW,YAAW,YAAY;IAC3C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAM;gBAER,OAAO,GAAE,SAAS,GAAG,SAAqB,EAAE,MAAM,CAAC,EAAE,MAAM;IAMvE,SAAS,IAAI,MAAM;IAInB;;;;;OAKG;IACG,gBAAgB,CAAC,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuDhF,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAS7C;;OAEG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB7E;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA4ClD;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAUrD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAE5D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,UAAU,CAEnE"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TON Chain Adapter
|
|
4
|
+
*
|
|
5
|
+
* Builds TON blockchain transactions using Cell/BoC serialization,
|
|
6
|
+
* attaches Ed25519 signatures from the FROST threshold signing
|
|
7
|
+
* network, and broadcasts via TON Center API.
|
|
8
|
+
*
|
|
9
|
+
* Requires: npm install @ton/ton
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TonAdapter = void 0;
|
|
13
|
+
exports.createTonAdapter = createTonAdapter;
|
|
14
|
+
exports.createTonTestnetAdapter = createTonTestnetAdapter;
|
|
15
|
+
const errors_1 = require("../utils/errors");
|
|
16
|
+
const optional_deps_1 = require("../utils/optional-deps");
|
|
17
|
+
const DEFAULT_RPCS = {
|
|
18
|
+
'mainnet': 'https://toncenter.com/api/v2',
|
|
19
|
+
'testnet': 'https://testnet.toncenter.com/api/v2',
|
|
20
|
+
};
|
|
21
|
+
class TonAdapter {
|
|
22
|
+
constructor(network = 'mainnet', rpcUrl) {
|
|
23
|
+
this.network = network;
|
|
24
|
+
this.rpcUrl = rpcUrl || DEFAULT_RPCS[network];
|
|
25
|
+
this.tonSdk = (0, optional_deps_1.requireOptionalDependency)('@ton/ton', 'ton');
|
|
26
|
+
}
|
|
27
|
+
getRpcUrl() {
|
|
28
|
+
return this.rpcUrl;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Build an unsigned TON transaction.
|
|
32
|
+
*
|
|
33
|
+
* TON uses Cell tree serialization. The signing payload is the
|
|
34
|
+
* SHA-256 hash of the external message body cell.
|
|
35
|
+
*/
|
|
36
|
+
async buildTransaction(tx, fromAddress) {
|
|
37
|
+
try {
|
|
38
|
+
const { TonClient, WalletContractV4, internal, Address, toNano, beginCell } = this.tonSdk;
|
|
39
|
+
const client = new TonClient({
|
|
40
|
+
endpoint: this.rpcUrl,
|
|
41
|
+
});
|
|
42
|
+
const address = Address.parse(fromAddress);
|
|
43
|
+
// Get seqno (sequence number) from wallet contract
|
|
44
|
+
const contract = client.open(WalletContractV4.create({
|
|
45
|
+
workchain: 0,
|
|
46
|
+
publicKey: Buffer.alloc(32), // placeholder
|
|
47
|
+
}));
|
|
48
|
+
// Build the internal message
|
|
49
|
+
const internalMsg = internal({
|
|
50
|
+
to: Address.parse(tx.to),
|
|
51
|
+
value: BigInt(tx.amount),
|
|
52
|
+
body: tx.payload ? beginCell().storeStringTail(tx.payload).endCell() : undefined,
|
|
53
|
+
bounce: true,
|
|
54
|
+
});
|
|
55
|
+
// Create the transfer message body
|
|
56
|
+
const body = beginCell()
|
|
57
|
+
.storeUint(0, 32) // seqno placeholder
|
|
58
|
+
.storeUint(Math.floor(Date.now() / 1000) + 60, 32) // expiry
|
|
59
|
+
.storeUint(0, 8) // mode: 0 = pay transfer fees separately
|
|
60
|
+
.storeRef(beginCell()
|
|
61
|
+
.store(internalMsg)
|
|
62
|
+
.endCell())
|
|
63
|
+
.endCell();
|
|
64
|
+
const bodyHash = body.hash();
|
|
65
|
+
const payload = {
|
|
66
|
+
signingHash: Buffer.from(bodyHash).toString('hex'),
|
|
67
|
+
body: body.toBoc().toString('hex'),
|
|
68
|
+
fromAddress,
|
|
69
|
+
toAddress: tx.to,
|
|
70
|
+
amount: tx.amount,
|
|
71
|
+
payload: tx.payload || '',
|
|
72
|
+
};
|
|
73
|
+
return Buffer.from(JSON.stringify(payload)).toString('hex');
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
if (e instanceof errors_1.ChainError)
|
|
77
|
+
throw e;
|
|
78
|
+
throw new errors_1.ChainError(`Failed to build TON transaction: ${e.message}`, 'ton');
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
getSigningPayload(unsignedTx) {
|
|
82
|
+
try {
|
|
83
|
+
const payload = JSON.parse(Buffer.from(unsignedTx, 'hex').toString());
|
|
84
|
+
return payload.signingHash;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return unsignedTx;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Attach an Ed25519 signature to the TON transaction
|
|
92
|
+
*/
|
|
93
|
+
async attachSignature(unsignedTx, signature) {
|
|
94
|
+
try {
|
|
95
|
+
const payload = JSON.parse(Buffer.from(unsignedTx, 'hex').toString());
|
|
96
|
+
const sig = signature.startsWith('0x') ? signature.slice(2) : signature;
|
|
97
|
+
const signedPayload = {
|
|
98
|
+
...payload,
|
|
99
|
+
signature: sig,
|
|
100
|
+
};
|
|
101
|
+
return Buffer.from(JSON.stringify(signedPayload)).toString('hex');
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
throw new errors_1.ChainError(`Failed to attach TON signature: ${e.message}`, 'ton');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Broadcast a signed TON transaction
|
|
109
|
+
*/
|
|
110
|
+
async broadcast(signedTx) {
|
|
111
|
+
try {
|
|
112
|
+
const { TonClient, Cell, beginCell } = this.tonSdk;
|
|
113
|
+
const payload = JSON.parse(Buffer.from(signedTx, 'hex').toString());
|
|
114
|
+
const client = new TonClient({ endpoint: this.rpcUrl });
|
|
115
|
+
// Reconstruct the signed external message
|
|
116
|
+
const bodyBoc = Buffer.from(payload.body, 'hex');
|
|
117
|
+
const body = Cell.fromBoc(bodyBoc)[0];
|
|
118
|
+
const sigBytes = Buffer.from(payload.signature, 'hex');
|
|
119
|
+
// Prepend signature to message body
|
|
120
|
+
const signedBody = beginCell()
|
|
121
|
+
.storeBuffer(sigBytes)
|
|
122
|
+
.storeSlice(body.beginParse())
|
|
123
|
+
.endCell();
|
|
124
|
+
// Create external message
|
|
125
|
+
const ext = beginCell()
|
|
126
|
+
.storeUint(0b10, 2) // ext_in_msg_info
|
|
127
|
+
.storeUint(0, 2) // src: addr_none
|
|
128
|
+
.storeAddress(null) // dest: will be set
|
|
129
|
+
.storeCoins(0) // import_fee
|
|
130
|
+
.storeBit(false) // state_init: none
|
|
131
|
+
.storeBit(true) // body: in reference
|
|
132
|
+
.storeRef(signedBody)
|
|
133
|
+
.endCell();
|
|
134
|
+
await client.sendFile(ext.toBoc());
|
|
135
|
+
// TON doesn't return a hash on send — compute it from the BoC
|
|
136
|
+
const crypto = require('crypto');
|
|
137
|
+
const hash = crypto.createHash('sha256').update(ext.toBoc()).digest('hex');
|
|
138
|
+
return hash;
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
if (e instanceof errors_1.ChainError)
|
|
142
|
+
throw e;
|
|
143
|
+
throw new errors_1.ChainError(`Failed to broadcast TON tx: ${e.message}`, 'ton');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get TON balance in nanotons
|
|
148
|
+
*/
|
|
149
|
+
async getBalance(address) {
|
|
150
|
+
try {
|
|
151
|
+
const { TonClient, Address } = this.tonSdk;
|
|
152
|
+
const client = new TonClient({ endpoint: this.rpcUrl });
|
|
153
|
+
const balance = await client.getBalance(Address.parse(address));
|
|
154
|
+
return balance.toString();
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return '0';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
exports.TonAdapter = TonAdapter;
|
|
162
|
+
function createTonAdapter(rpcUrl) {
|
|
163
|
+
return new TonAdapter('mainnet', rpcUrl);
|
|
164
|
+
}
|
|
165
|
+
function createTonTestnetAdapter(rpcUrl) {
|
|
166
|
+
return new TonAdapter('testnet', rpcUrl);
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=ton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../src/chains/ton.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TRON Chain Adapter
|
|
3
|
+
*
|
|
4
|
+
* Builds TRON transactions using Protobuf serialization (NOT EVM RLP),
|
|
5
|
+
* attaches secp256k1 ECDSA signatures from the FROST threshold signing
|
|
6
|
+
* network, and broadcasts via TRON full node HTTP API.
|
|
7
|
+
*
|
|
8
|
+
* Requires: npm install tronweb
|
|
9
|
+
*/
|
|
10
|
+
import { ChainAdapter, TronTransaction } from '../core/types';
|
|
11
|
+
export declare class TronAdapter implements ChainAdapter {
|
|
12
|
+
private rpcUrl;
|
|
13
|
+
private network;
|
|
14
|
+
private tronWeb;
|
|
15
|
+
constructor(network?: 'mainnet' | 'shasta' | 'nile', rpcUrl?: string);
|
|
16
|
+
getRpcUrl(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Build an unsigned TRON transaction.
|
|
19
|
+
*
|
|
20
|
+
* TRON uses Protobuf for TX serialization. The signing payload
|
|
21
|
+
* is SHA-256 of the raw transaction data (returned as txID by TronWeb).
|
|
22
|
+
*/
|
|
23
|
+
buildTransaction(tx: TronTransaction, fromAddress: string): Promise<string>;
|
|
24
|
+
getSigningPayload(unsignedTx: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Attach a secp256k1 ECDSA signature to the TRON transaction.
|
|
27
|
+
* TRON expects 65-byte signatures (r + s + v), same format as EVM.
|
|
28
|
+
*/
|
|
29
|
+
attachSignature(unsignedTx: string, signature: string): Promise<string>;
|
|
30
|
+
/**
|
|
31
|
+
* Broadcast a signed TRON transaction
|
|
32
|
+
*/
|
|
33
|
+
broadcast(signedTx: string): Promise<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Get TRX balance in SUN
|
|
36
|
+
*/
|
|
37
|
+
getBalance(address: string): Promise<string>;
|
|
38
|
+
}
|
|
39
|
+
export declare function createTronAdapter(rpcUrl?: string): TronAdapter;
|
|
40
|
+
export declare function createTronShastaAdapter(rpcUrl?: string): TronAdapter;
|
|
41
|
+
//# sourceMappingURL=tron.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tron.d.ts","sourceRoot":"","sources":["../../src/chains/tron.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAU9D,qBAAa,WAAY,YAAW,YAAY;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAM;gBAET,OAAO,GAAE,SAAS,GAAG,QAAQ,GAAG,MAAkB,EAAE,MAAM,CAAC,EAAE,MAAM;IAO/E,SAAS,IAAI,MAAM;IAInB;;;;;OAKG;IACG,gBAAgB,CAAC,EAAE,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAwBjF,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAS7C;;;OAGG;IACG,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB7E;;OAEG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA2BlD;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAQrD;AAED,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAE9D;AAED,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAEpE"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* TRON Chain Adapter
|
|
4
|
+
*
|
|
5
|
+
* Builds TRON transactions using Protobuf serialization (NOT EVM RLP),
|
|
6
|
+
* attaches secp256k1 ECDSA signatures from the FROST threshold signing
|
|
7
|
+
* network, and broadcasts via TRON full node HTTP API.
|
|
8
|
+
*
|
|
9
|
+
* Requires: npm install tronweb
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.TronAdapter = void 0;
|
|
13
|
+
exports.createTronAdapter = createTronAdapter;
|
|
14
|
+
exports.createTronShastaAdapter = createTronShastaAdapter;
|
|
15
|
+
const errors_1 = require("../utils/errors");
|
|
16
|
+
const optional_deps_1 = require("../utils/optional-deps");
|
|
17
|
+
const DEFAULT_RPCS = {
|
|
18
|
+
'mainnet': 'https://api.trongrid.io',
|
|
19
|
+
'shasta': 'https://api.shasta.trongrid.io',
|
|
20
|
+
'nile': 'https://nile.trongrid.io',
|
|
21
|
+
};
|
|
22
|
+
class TronAdapter {
|
|
23
|
+
constructor(network = 'mainnet', rpcUrl) {
|
|
24
|
+
this.network = network;
|
|
25
|
+
this.rpcUrl = rpcUrl || DEFAULT_RPCS[network];
|
|
26
|
+
const TronWeb = (0, optional_deps_1.requireOptionalDependency)('tronweb', 'tron');
|
|
27
|
+
this.tronWeb = new TronWeb({ fullHost: this.rpcUrl });
|
|
28
|
+
}
|
|
29
|
+
getRpcUrl() {
|
|
30
|
+
return this.rpcUrl;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build an unsigned TRON transaction.
|
|
34
|
+
*
|
|
35
|
+
* TRON uses Protobuf for TX serialization. The signing payload
|
|
36
|
+
* is SHA-256 of the raw transaction data (returned as txID by TronWeb).
|
|
37
|
+
*/
|
|
38
|
+
async buildTransaction(tx, fromAddress) {
|
|
39
|
+
try {
|
|
40
|
+
const unsignedTx = await this.tronWeb.transactionBuilder.sendTrx(tx.to, tx.amount, fromAddress);
|
|
41
|
+
// txID is already SHA-256(rawData) — the signing hash
|
|
42
|
+
const payload = {
|
|
43
|
+
signingHash: unsignedTx.txID,
|
|
44
|
+
rawData: unsignedTx.raw_data,
|
|
45
|
+
rawDataHex: unsignedTx.raw_data_hex,
|
|
46
|
+
};
|
|
47
|
+
return Buffer.from(JSON.stringify(payload)).toString('hex');
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
throw new errors_1.ChainError(`Failed to build TRON transaction: ${e.message}`, 'tron');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
getSigningPayload(unsignedTx) {
|
|
54
|
+
try {
|
|
55
|
+
const payload = JSON.parse(Buffer.from(unsignedTx, 'hex').toString());
|
|
56
|
+
return payload.signingHash;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return unsignedTx;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Attach a secp256k1 ECDSA signature to the TRON transaction.
|
|
64
|
+
* TRON expects 65-byte signatures (r + s + v), same format as EVM.
|
|
65
|
+
*/
|
|
66
|
+
async attachSignature(unsignedTx, signature) {
|
|
67
|
+
try {
|
|
68
|
+
const payload = JSON.parse(Buffer.from(unsignedTx, 'hex').toString());
|
|
69
|
+
const sig = signature.startsWith('0x') ? signature.slice(2) : signature;
|
|
70
|
+
const signedPayload = {
|
|
71
|
+
...payload,
|
|
72
|
+
signature: [sig],
|
|
73
|
+
};
|
|
74
|
+
return Buffer.from(JSON.stringify(signedPayload)).toString('hex');
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
throw new errors_1.ChainError(`Failed to attach TRON signature: ${e.message}`, 'tron');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Broadcast a signed TRON transaction
|
|
82
|
+
*/
|
|
83
|
+
async broadcast(signedTx) {
|
|
84
|
+
try {
|
|
85
|
+
const payload = JSON.parse(Buffer.from(signedTx, 'hex').toString());
|
|
86
|
+
const signedTransaction = {
|
|
87
|
+
txID: payload.signingHash,
|
|
88
|
+
raw_data: payload.rawData,
|
|
89
|
+
raw_data_hex: payload.rawDataHex,
|
|
90
|
+
signature: payload.signature,
|
|
91
|
+
};
|
|
92
|
+
const result = await this.tronWeb.trx.sendRawTransaction(signedTransaction);
|
|
93
|
+
if (!result.result && !result.txid) {
|
|
94
|
+
throw new Error(result.message || 'Broadcast failed');
|
|
95
|
+
}
|
|
96
|
+
return result.txid || payload.signingHash;
|
|
97
|
+
}
|
|
98
|
+
catch (e) {
|
|
99
|
+
if (e instanceof errors_1.ChainError)
|
|
100
|
+
throw e;
|
|
101
|
+
throw new errors_1.ChainError(`Failed to broadcast TRON tx: ${e.message}`, 'tron');
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get TRX balance in SUN
|
|
106
|
+
*/
|
|
107
|
+
async getBalance(address) {
|
|
108
|
+
try {
|
|
109
|
+
const balance = await this.tronWeb.trx.getBalance(address);
|
|
110
|
+
return balance.toString();
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
return '0';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.TronAdapter = TronAdapter;
|
|
118
|
+
function createTronAdapter(rpcUrl) {
|
|
119
|
+
return new TronAdapter('mainnet', rpcUrl);
|
|
120
|
+
}
|
|
121
|
+
function createTronShastaAdapter(rpcUrl) {
|
|
122
|
+
return new TronAdapter('shasta', rpcUrl);
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=tron.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tron.js","sourceRoot":"","sources":["../../src/chains/tron.ts"],"names":[],"mappings":"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"}
|
package/dist/core/client.d.ts
CHANGED
|
@@ -238,13 +238,12 @@ export declare class Sequence0 {
|
|
|
238
238
|
private getRpcUrl;
|
|
239
239
|
private getCurveForChain;
|
|
240
240
|
/**
|
|
241
|
-
* Build an ownership proof for a sign request.
|
|
241
|
+
* Build an ownership proof for a sign request using EIP-712 typed structured data.
|
|
242
242
|
*
|
|
243
|
-
*
|
|
243
|
+
* EIP-712 domain: { name: "Sequence0", version: "1", chainId, verifyingContract: WalletFactory }
|
|
244
|
+
* EIP-712 type: Sequence0Auth(string walletId, string action, uint256 timestamp)
|
|
244
245
|
*
|
|
245
|
-
*
|
|
246
|
-
* - message_hex_bytes: the raw bytes of the hex-encoded message (i.e. the message as passed to /sign)
|
|
247
|
-
* - timestamp_be_bytes: 8-byte big-endian encoding of the Unix epoch second
|
|
246
|
+
* The digest is: keccak256("\x19\x01" || domainSeparator || hashStruct)
|
|
248
247
|
*
|
|
249
248
|
* Returns null when no ownerSigner is configured (backwards compatible).
|
|
250
249
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACH,aAAa,EACb,mBAAmB,EAEnB,cAAc,EACd,cAAc,EAEd,YAAY,EAGZ,kBAAkB,EAErB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,MAAM,EAAgB,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,QAAQ,EAAa,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAc,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EACH,aAAa,EACb,mBAAmB,EAEnB,cAAc,EACd,cAAc,EAEd,YAAY,EAGZ,kBAAkB,EAErB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,MAAM,EAAgB,MAAM,kBAAkB,CAAC;AAExD,OAAO,EAAE,QAAQ,EAAa,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAc,aAAa,EAAE,MAAM,cAAc,CAAC;AAsIzD,qBAAa,SAAS;IAClB,OAAO,CAAC,MAAM,CAA2D;IACzE,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,EAAE,CAAyB;IACnC,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,cAAc,CAAwC;IAC9D,4EAA4E;IAC5E,OAAO,CAAC,YAAY,CAAkC;IACtD,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAA4B;IAC/C,wEAAwE;IACxE,OAAO,CAAC,YAAY,CAAuB;IAE3C;;;;;;;;;;;;;;;;;;;;;;OAsBG;gBACS,MAAM,EAAE,aAAa;IAyEjC;;;OAGG;YACW,OAAO;IAYrB;;;OAGG;YACW,WAAW;IAwBzB;;;;OAIG;YACW,mBAAmB;IA0BjC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;;;OAIG;YACW,YAAY;IAoC1B;;;;;;;;;;;;OAYG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IA8GjE;;;;;;;;;;OAUG;IACG,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BlD;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAY5C;;;;;;OAMG;IACG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB1E;;;;;OAKG;IACG,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAYxE;;;;;;;OAOG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IA8CzF;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,CAAC;IAO1C;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAOvC;;;OAGG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlD;;OAEG;IACG,cAAc;IAIpB;;;OAGG;IACG,iBAAiB;IAQvB;;;;;;;;;;;;;;;;OAgBG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC;IAKxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkCjE;;;;;;;;;OASG;IACG,SAAS,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IAWrD;;;OAGG;IACH,OAAO,IAAI,IAAI;YAyBD,WAAW;IAUzB,OAAO,CAAC,SAAS;IAMjB,OAAO,CAAC,gBAAgB;IAexB;;;;;;;;;OASG;YACW,kBAAkB;IAuBhC;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAkC5B;;OAEG;IACH,OAAO,CAAC,UAAU;IAWlB,OAAO,CAAC,gBAAgB;CAK3B"}
|
package/dist/core/client.js
CHANGED
|
@@ -32,7 +32,24 @@ const websocket_1 = require("../utils/websocket");
|
|
|
32
32
|
const discovery_1 = require("../utils/discovery");
|
|
33
33
|
const fee_1 = require("../utils/fee");
|
|
34
34
|
const errors_1 = require("../utils/errors");
|
|
35
|
+
const eip712_1 = require("../utils/eip712");
|
|
35
36
|
const validation_1 = require("../utils/validation");
|
|
37
|
+
/**
|
|
38
|
+
* Cryptographically secure random number in [0, 1).
|
|
39
|
+
* Replaces Math.random() for agent selection to prevent prediction attacks.
|
|
40
|
+
*/
|
|
41
|
+
function secureRandom() {
|
|
42
|
+
const array = new Uint32Array(1);
|
|
43
|
+
if (typeof globalThis.crypto !== 'undefined') {
|
|
44
|
+
globalThis.crypto.getRandomValues(array);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Node.js fallback
|
|
48
|
+
const { randomBytes } = require('crypto');
|
|
49
|
+
array[0] = randomBytes(4).readUInt32BE(0);
|
|
50
|
+
}
|
|
51
|
+
return array[0] / (0xFFFFFFFF + 1);
|
|
52
|
+
}
|
|
36
53
|
/** Default agent URL for testnet (we run these ourselves) */
|
|
37
54
|
const TESTNET_AGENT_URL = 'http://3.140.248.117:8080';
|
|
38
55
|
/** Module-level flag to emit HTTP warning only once */
|
|
@@ -46,13 +63,13 @@ const SEQUENCE_RPC = {
|
|
|
46
63
|
};
|
|
47
64
|
/** AgentRegistry contract addresses */
|
|
48
65
|
const REGISTRY_ADDRESSES = {
|
|
49
|
-
testnet: '
|
|
50
|
-
mainnet: '
|
|
66
|
+
testnet: '0xe00bc0ad2d623ea021c9299221125b4e5951cdab',
|
|
67
|
+
mainnet: '0x774d9a0dc937bfdc7636cbc6e0fc37f9a0809177',
|
|
51
68
|
};
|
|
52
69
|
/** FeeCollector contract addresses */
|
|
53
70
|
const FEE_COLLECTOR_ADDRESSES = {
|
|
54
|
-
testnet: '
|
|
55
|
-
mainnet: '
|
|
71
|
+
testnet: '0x2a23644695fb62f6ab2dffdaf58fc1ce89f3bada',
|
|
72
|
+
mainnet: '0x1977f852aa0d16a59c4ea71b6cc72db02803395f',
|
|
56
73
|
};
|
|
57
74
|
/** Default chain RPC URLs */
|
|
58
75
|
const CHAIN_RPCS = {
|
|
@@ -254,12 +271,12 @@ class Sequence0 {
|
|
|
254
271
|
// If all healthy agents have been excluded, clear exclusions and try again
|
|
255
272
|
if (healthy.length > 0) {
|
|
256
273
|
this.failedAgents.clear();
|
|
257
|
-
const idx = Math.floor(
|
|
274
|
+
const idx = Math.floor(secureRandom() * healthy.length);
|
|
258
275
|
return healthy[idx].apiUrl;
|
|
259
276
|
}
|
|
260
277
|
throw new errors_1.NetworkError('No healthy agents found in the registry. The network may not have active node runners yet.');
|
|
261
278
|
}
|
|
262
|
-
const idx = Math.floor(
|
|
279
|
+
const idx = Math.floor(secureRandom() * available.length);
|
|
263
280
|
return available[idx].apiUrl;
|
|
264
281
|
}
|
|
265
282
|
/**
|
|
@@ -431,6 +448,9 @@ class Sequence0 {
|
|
|
431
448
|
catch (e) {
|
|
432
449
|
if (e instanceof errors_1.DkgError)
|
|
433
450
|
throw e;
|
|
451
|
+
// Propagate validation errors from malformed agent responses
|
|
452
|
+
if (e instanceof errors_1.Sequence0Error && e.code === 'INVALID_RESPONSE')
|
|
453
|
+
throw e;
|
|
434
454
|
throw new errors_1.DkgError(`DKG ceremony timed out after ${timeout}ms. The agent network may be busy.`);
|
|
435
455
|
}
|
|
436
456
|
// Derive address from public key based on chain
|
|
@@ -552,9 +572,15 @@ class Sequence0 {
|
|
|
552
572
|
try {
|
|
553
573
|
const ws = await this.getWsClient();
|
|
554
574
|
const result = await ws.waitFor('SigningComplete', (e) => e.request_id === requestId, timeoutMs);
|
|
555
|
-
|
|
575
|
+
// Validate the WebSocket signing result before using
|
|
576
|
+
const validated = (0, validation_1.validateSignResultResponse)({ ...result, status: 'complete' }, 'ws:SigningComplete');
|
|
577
|
+
return validated.signature;
|
|
556
578
|
}
|
|
557
|
-
catch {
|
|
579
|
+
catch (e) {
|
|
580
|
+
// If validation failed, propagate it — only swallow connection errors
|
|
581
|
+
if (e instanceof errors_1.Sequence0Error && e.code === 'INVALID_RESPONSE') {
|
|
582
|
+
throw e;
|
|
583
|
+
}
|
|
558
584
|
// Fall back to polling
|
|
559
585
|
}
|
|
560
586
|
// Polling fallback
|
|
@@ -600,11 +626,12 @@ class Sequence0 {
|
|
|
600
626
|
throw new errors_1.Sequence0Error('ownerSigner or ownerPrivateKey is required to sign refresh requests');
|
|
601
627
|
}
|
|
602
628
|
return this.withFailover(async (http) => {
|
|
603
|
-
await http.post('/refresh', {
|
|
629
|
+
const rawResponse = await http.post('/refresh', {
|
|
604
630
|
wallet_id: walletId,
|
|
605
631
|
owner_signature: proof.owner_signature,
|
|
606
632
|
timestamp: proof.timestamp,
|
|
607
633
|
});
|
|
634
|
+
(0, validation_1.validateRefreshResponse)(rawResponse, '/refresh');
|
|
608
635
|
});
|
|
609
636
|
}
|
|
610
637
|
/**
|
|
@@ -733,6 +760,13 @@ class Sequence0 {
|
|
|
733
760
|
}
|
|
734
761
|
this.circuitBreaker.resetAll();
|
|
735
762
|
this.failedAgents.clear();
|
|
763
|
+
// Clear sensitive references
|
|
764
|
+
this.ownerSigner = undefined;
|
|
765
|
+
this.ownerAddress = undefined;
|
|
766
|
+
// Clear config reference that may hold ownerPrivateKey
|
|
767
|
+
if (this.config) {
|
|
768
|
+
delete this.config.ownerPrivateKey;
|
|
769
|
+
}
|
|
736
770
|
}
|
|
737
771
|
// ────────────────────────────────────────────────
|
|
738
772
|
// Internals
|
|
@@ -767,32 +801,23 @@ class Sequence0 {
|
|
|
767
801
|
return 'secp256k1';
|
|
768
802
|
}
|
|
769
803
|
/**
|
|
770
|
-
* Build an ownership proof for a sign request.
|
|
804
|
+
* Build an ownership proof for a sign request using EIP-712 typed structured data.
|
|
771
805
|
*
|
|
772
|
-
*
|
|
806
|
+
* EIP-712 domain: { name: "Sequence0", version: "1", chainId, verifyingContract: WalletFactory }
|
|
807
|
+
* EIP-712 type: Sequence0Auth(string walletId, string action, uint256 timestamp)
|
|
773
808
|
*
|
|
774
|
-
*
|
|
775
|
-
* - message_hex_bytes: the raw bytes of the hex-encoded message (i.e. the message as passed to /sign)
|
|
776
|
-
* - timestamp_be_bytes: 8-byte big-endian encoding of the Unix epoch second
|
|
809
|
+
* The digest is: keccak256("\x19\x01" || domainSeparator || hashStruct)
|
|
777
810
|
*
|
|
778
811
|
* Returns null when no ownerSigner is configured (backwards compatible).
|
|
779
812
|
*/
|
|
780
|
-
async signOwnershipProof(walletId,
|
|
813
|
+
async signOwnershipProof(walletId, action) {
|
|
781
814
|
if (!this.ownerSigner)
|
|
782
815
|
return null;
|
|
783
816
|
const timestamp = Math.floor(Date.now() / 1000);
|
|
784
|
-
|
|
785
|
-
const
|
|
786
|
-
|
|
787
|
-
const
|
|
788
|
-
// timestamp as 8-byte big-endian
|
|
789
|
-
const timestampBytes = new Uint8Array(8);
|
|
790
|
-
const view = new DataView(timestampBytes.buffer);
|
|
791
|
-
// DataView setBigUint64 writes big-endian by default
|
|
792
|
-
view.setBigUint64(0, BigInt(timestamp), false);
|
|
793
|
-
// Concatenate and hash: keccak256(walletId + message + timestamp)
|
|
794
|
-
const payload = (0, ethers_1.concat)([walletIdBytes, messageBytes, timestampBytes]);
|
|
795
|
-
const digest = (0, ethers_1.getBytes)((0, ethers_1.keccak256)(payload));
|
|
817
|
+
const network = this.config.network;
|
|
818
|
+
const chainId = eip712_1.SEQUENCE0_CHAIN_IDS[network] || eip712_1.SEQUENCE0_CHAIN_IDS.mainnet;
|
|
819
|
+
const walletFactory = eip712_1.WALLET_FACTORY_ADDRESSES[network] || eip712_1.WALLET_FACTORY_ADDRESSES.mainnet;
|
|
820
|
+
const digest = (0, eip712_1.computeEip712Digest)(walletId, action, timestamp, chainId, walletFactory);
|
|
796
821
|
// Sign the digest
|
|
797
822
|
const signature = await this.ownerSigner(digest);
|
|
798
823
|
return {
|
|
@@ -815,7 +840,7 @@ class Sequence0 {
|
|
|
815
840
|
const remaining = [...weighted];
|
|
816
841
|
for (let i = 0; i < n && remaining.length > 0; i++) {
|
|
817
842
|
const totalWeight = remaining.reduce((sum, w) => sum + w.weight, 0);
|
|
818
|
-
let rand =
|
|
843
|
+
let rand = secureRandom() * totalWeight;
|
|
819
844
|
let picked = remaining.length - 1; // fallback to last
|
|
820
845
|
for (let j = 0; j < remaining.length; j++) {
|
|
821
846
|
rand -= remaining[j].weight;
|
|
@@ -842,7 +867,7 @@ class Sequence0 {
|
|
|
842
867
|
}
|
|
843
868
|
generateWalletId() {
|
|
844
869
|
const timestamp = Date.now().toString(36);
|
|
845
|
-
const random =
|
|
870
|
+
const random = secureRandom().toString(36).slice(2, 8);
|
|
846
871
|
return `s0-${timestamp}-${random}`;
|
|
847
872
|
}
|
|
848
873
|
}
|