@r3e/neo-js-sdk 0.3.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 +117 -0
- package/dist/constants.d.ts +25 -0
- package/dist/constants.js +34 -0
- package/dist/core/block.d.ts +65 -0
- package/dist/core/block.js +128 -0
- package/dist/core/hash.d.ts +20 -0
- package/dist/core/hash.js +51 -0
- package/dist/core/keypair.d.ts +24 -0
- package/dist/core/keypair.js +97 -0
- package/dist/core/opcode.d.ts +3 -0
- package/dist/core/opcode.js +2 -0
- package/dist/core/script.d.ts +25 -0
- package/dist/core/script.js +144 -0
- package/dist/core/serializing.d.ts +40 -0
- package/dist/core/serializing.js +175 -0
- package/dist/core/tx.d.ts +147 -0
- package/dist/core/tx.js +252 -0
- package/dist/core/witness-rule.d.ts +128 -0
- package/dist/core/witness-rule.js +201 -0
- package/dist/core/witness.d.ts +24 -0
- package/dist/core/witness.js +62 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +15 -0
- package/dist/internal/bytes.d.ts +11 -0
- package/dist/internal/bytes.js +55 -0
- package/dist/internal/hex.d.ts +2 -0
- package/dist/internal/hex.js +10 -0
- package/dist/rpcclient/index.d.ts +166 -0
- package/dist/rpcclient/index.js +539 -0
- package/dist/rpcclient/parse.d.ts +16 -0
- package/dist/rpcclient/parse.js +48 -0
- package/dist/rpcclient/types.d.ts +640 -0
- package/dist/rpcclient/types.js +1 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.js +40 -0
- package/dist/wallet/index.d.ts +2 -0
- package/dist/wallet/index.js +2 -0
- package/dist/wallet/nep2.d.ts +19 -0
- package/dist/wallet/nep2.js +96 -0
- package/dist/wallet/nep6.d.ts +136 -0
- package/dist/wallet/nep6.js +178 -0
- package/package.json +62 -0
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# neo-js-sdk
|
|
2
|
+
|
|
3
|
+
Neo N3 JavaScript/TypeScript SDK with a typed RPC client, core transaction primitives, and NEP-2 / NEP-6 wallet helpers.
|
|
4
|
+
|
|
5
|
+
## What It Includes
|
|
6
|
+
|
|
7
|
+
- Neo N3 network constants and native contract hash helpers
|
|
8
|
+
- `H160` / `H256` hash wrappers
|
|
9
|
+
- Binary serialization helpers
|
|
10
|
+
- `PrivateKey`, `PublicKey`, `Witness`, `Signer`, `Tx`, `Header`, `Block`, `TrimmedBlock`
|
|
11
|
+
- `ScriptBuilder`, `OpCode`, `CallFlags`
|
|
12
|
+
- NEP-2 helpers and NEP-6 wallet/account models
|
|
13
|
+
- Typed JSON-RPC coverage across core, state-service, and wallet-node methods with modeled outputs and object-based inputs
|
|
14
|
+
- A single canonical `camelCase` API surface for JavaScript and TypeScript consumers
|
|
15
|
+
|
|
16
|
+
## Install
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install neo-js-sdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Verification
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm run typecheck
|
|
26
|
+
npm test
|
|
27
|
+
npm run build
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Optional live RPC smoke test against Neo testnet:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm run test:integration
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Override the default testnet endpoint if needed:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
NEO_RPC_URL=https://your-rpc-node npm run test:integration
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Usage
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
import {
|
|
46
|
+
CallFlags,
|
|
47
|
+
InvokeParameters,
|
|
48
|
+
PrivateKey,
|
|
49
|
+
RpcClient,
|
|
50
|
+
ScriptBuilder,
|
|
51
|
+
Signer,
|
|
52
|
+
Tx,
|
|
53
|
+
WitnessScope,
|
|
54
|
+
gasContractHash,
|
|
55
|
+
testNetworkId
|
|
56
|
+
} from "neo-js-sdk";
|
|
57
|
+
|
|
58
|
+
const privateKey = new PrivateKey(
|
|
59
|
+
"f046222512e7258c62f56f5e9e624d08c8dc38f336a15f320b3501ec7e90d7c6"
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const script = new ScriptBuilder()
|
|
63
|
+
.emitContractCall(gasContractHash(), "transfer", CallFlags.All, [
|
|
64
|
+
"from",
|
|
65
|
+
"to",
|
|
66
|
+
1
|
|
67
|
+
])
|
|
68
|
+
.toBytes();
|
|
69
|
+
|
|
70
|
+
const tx = new Tx({
|
|
71
|
+
nonce: 1,
|
|
72
|
+
systemFee: 1_0000000n,
|
|
73
|
+
networkFee: 1_0000000n,
|
|
74
|
+
validUntilBlock: 100,
|
|
75
|
+
script,
|
|
76
|
+
signers: [
|
|
77
|
+
new Signer({
|
|
78
|
+
account: privateKey.publicKey().getScriptHash(),
|
|
79
|
+
scopes: WitnessScope.CalledByEntry
|
|
80
|
+
})
|
|
81
|
+
]
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
tx.witnesses = [privateKey.signWitness(tx.getSignData(testNetworkId()))];
|
|
85
|
+
|
|
86
|
+
const client = new RpcClient("https://seed1t5.neo.org:20332");
|
|
87
|
+
await client.sendRawTransaction({ tx });
|
|
88
|
+
|
|
89
|
+
const invoke = await client.invokeFunction({
|
|
90
|
+
contractHash: gasContractHash(),
|
|
91
|
+
method: "balanceOf",
|
|
92
|
+
args: new InvokeParameters().addHash160(privateKey.publicKey().getScriptHash())
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Wallet Helpers
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import { Wallet } from "neo-js-sdk";
|
|
100
|
+
|
|
101
|
+
const wallet = new Wallet({ name: "demo", passphrase: "secret" });
|
|
102
|
+
const account = wallet.createAccount();
|
|
103
|
+
|
|
104
|
+
wallet.writeToFile("./wallet.json");
|
|
105
|
+
|
|
106
|
+
const reopened = Wallet.openNep6Wallet("./wallet.json");
|
|
107
|
+
reopened.decrypt("secret");
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Development
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npm run typecheck
|
|
114
|
+
npm test
|
|
115
|
+
npm run build
|
|
116
|
+
npm run test:integration
|
|
117
|
+
```
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { H160 } from "./core/hash.js";
|
|
2
|
+
export declare const MAIN_NETWORK_ID = 860833102;
|
|
3
|
+
export declare const TEST_NETWORK_ID = 894710606;
|
|
4
|
+
export declare const ADDRESS_VERSION = 53;
|
|
5
|
+
export declare const NEO_CONTRACT_HASH = "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5";
|
|
6
|
+
export declare const GAS_CONTRACT_HASH = "0xd2a4cff31913016155e38e474a2c06d08be276cf";
|
|
7
|
+
export declare const STDLIB_CONTRACT_HASH = "0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0";
|
|
8
|
+
export declare const CRYPTOLIB_CONTRACT_HASH = "0x726cb6e0cd8628a1350a611384688911ab75f51b";
|
|
9
|
+
export declare const LEDGER_CONTRACT_HASH = "0xda65b600f7124ce6c79950c1772a36403104f2be";
|
|
10
|
+
export declare const ORACLE_CONTRACT_HASH = "0xfe924b7cfe89ddd271abaf7210a80a7e11178758";
|
|
11
|
+
export declare const POLICY_CONTRACT_HASH = "0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b";
|
|
12
|
+
export declare const NOTARY_CONTRACT_HASH = "0xc1e14f19c3e60d0b9244d06dd7ba9b113135ec3b";
|
|
13
|
+
export declare const ROLE_MANAGEMENT_CONTRACT_HASH = "0x49cf4e5378ffcd4dec034fd98a174c5491e395e2";
|
|
14
|
+
export declare function mainNetworkId(): number;
|
|
15
|
+
export declare function testNetworkId(): number;
|
|
16
|
+
export declare function addressVersion(): number;
|
|
17
|
+
export declare const neoContractHash: () => H160;
|
|
18
|
+
export declare const gasContractHash: () => H160;
|
|
19
|
+
export declare const stdlibContractHash: () => H160;
|
|
20
|
+
export declare const cryptolibContractHash: () => H160;
|
|
21
|
+
export declare const ledgerContractHash: () => H160;
|
|
22
|
+
export declare const oracleContractHash: () => H160;
|
|
23
|
+
export declare const policyContractHash: () => H160;
|
|
24
|
+
export declare const notaryContractHash: () => H160;
|
|
25
|
+
export declare const roleManagementContractHash: () => H160;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { H160 } from "./core/hash.js";
|
|
2
|
+
export const MAIN_NETWORK_ID = 860833102;
|
|
3
|
+
export const TEST_NETWORK_ID = 894710606;
|
|
4
|
+
export const ADDRESS_VERSION = 53;
|
|
5
|
+
export const NEO_CONTRACT_HASH = "0xef4073a0f2b305a38ec4050e4d3d28bc40ea63f5";
|
|
6
|
+
export const GAS_CONTRACT_HASH = "0xd2a4cff31913016155e38e474a2c06d08be276cf";
|
|
7
|
+
export const STDLIB_CONTRACT_HASH = "0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0";
|
|
8
|
+
export const CRYPTOLIB_CONTRACT_HASH = "0x726cb6e0cd8628a1350a611384688911ab75f51b";
|
|
9
|
+
export const LEDGER_CONTRACT_HASH = "0xda65b600f7124ce6c79950c1772a36403104f2be";
|
|
10
|
+
export const ORACLE_CONTRACT_HASH = "0xfe924b7cfe89ddd271abaf7210a80a7e11178758";
|
|
11
|
+
export const POLICY_CONTRACT_HASH = "0xcc5e4edd9f5f8dba8bb65734541df7a1c081c67b";
|
|
12
|
+
export const NOTARY_CONTRACT_HASH = "0xc1e14f19c3e60d0b9244d06dd7ba9b113135ec3b";
|
|
13
|
+
export const ROLE_MANAGEMENT_CONTRACT_HASH = "0x49cf4e5378ffcd4dec034fd98a174c5491e395e2";
|
|
14
|
+
function hashFactory(value) {
|
|
15
|
+
return () => new H160(value);
|
|
16
|
+
}
|
|
17
|
+
export function mainNetworkId() {
|
|
18
|
+
return MAIN_NETWORK_ID;
|
|
19
|
+
}
|
|
20
|
+
export function testNetworkId() {
|
|
21
|
+
return TEST_NETWORK_ID;
|
|
22
|
+
}
|
|
23
|
+
export function addressVersion() {
|
|
24
|
+
return ADDRESS_VERSION;
|
|
25
|
+
}
|
|
26
|
+
export const neoContractHash = hashFactory(NEO_CONTRACT_HASH);
|
|
27
|
+
export const gasContractHash = hashFactory(GAS_CONTRACT_HASH);
|
|
28
|
+
export const stdlibContractHash = hashFactory(STDLIB_CONTRACT_HASH);
|
|
29
|
+
export const cryptolibContractHash = hashFactory(CRYPTOLIB_CONTRACT_HASH);
|
|
30
|
+
export const ledgerContractHash = hashFactory(LEDGER_CONTRACT_HASH);
|
|
31
|
+
export const oracleContractHash = hashFactory(ORACLE_CONTRACT_HASH);
|
|
32
|
+
export const policyContractHash = hashFactory(POLICY_CONTRACT_HASH);
|
|
33
|
+
export const notaryContractHash = hashFactory(NOTARY_CONTRACT_HASH);
|
|
34
|
+
export const roleManagementContractHash = hashFactory(ROLE_MANAGEMENT_CONTRACT_HASH);
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { H160, H256 } from "./hash.js";
|
|
2
|
+
import { BinaryReader, BinaryWriter } from "./serializing.js";
|
|
3
|
+
import { Tx } from "./tx.js";
|
|
4
|
+
import { Witness } from "./witness.js";
|
|
5
|
+
export declare class Header {
|
|
6
|
+
readonly version: number;
|
|
7
|
+
readonly previousBlockHash: H256;
|
|
8
|
+
readonly merkleRoot: H256;
|
|
9
|
+
readonly unixMillis: bigint;
|
|
10
|
+
readonly nonce: number;
|
|
11
|
+
readonly index: number;
|
|
12
|
+
readonly primaryIndex: number;
|
|
13
|
+
readonly nextConsensus: H160;
|
|
14
|
+
readonly witness: Witness;
|
|
15
|
+
constructor({ version, previousBlockHash, merkleRoot, unixMillis, nonce, index, primaryIndex, nextConsensus, witness, }: {
|
|
16
|
+
version: number;
|
|
17
|
+
previousBlockHash: H256;
|
|
18
|
+
merkleRoot: H256;
|
|
19
|
+
unixMillis: bigint | number;
|
|
20
|
+
nonce: number;
|
|
21
|
+
index: number;
|
|
22
|
+
primaryIndex: number;
|
|
23
|
+
nextConsensus: H160;
|
|
24
|
+
witness: Witness;
|
|
25
|
+
});
|
|
26
|
+
get time(): bigint;
|
|
27
|
+
getSignData(networkId: number): Uint8Array;
|
|
28
|
+
marshalUnsignedTo(writer: BinaryWriter): void;
|
|
29
|
+
marshalTo(writer: BinaryWriter): void;
|
|
30
|
+
static unmarshalFrom(reader: BinaryReader): Header;
|
|
31
|
+
toBytes(): Uint8Array;
|
|
32
|
+
toJSON(): {
|
|
33
|
+
version: number;
|
|
34
|
+
previousblockhash: string;
|
|
35
|
+
merkleroot: string;
|
|
36
|
+
time: string;
|
|
37
|
+
nonce: number;
|
|
38
|
+
index: number;
|
|
39
|
+
primaryindex: number;
|
|
40
|
+
nextconsensus: string;
|
|
41
|
+
witness: ReturnType<Witness["toJSON"]>;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export declare class Block {
|
|
45
|
+
readonly header: Header;
|
|
46
|
+
readonly transactions: Tx[];
|
|
47
|
+
constructor(header: Header, transactions: Tx[]);
|
|
48
|
+
marshalTo(writer: BinaryWriter): void;
|
|
49
|
+
static unmarshalFrom(reader: BinaryReader): Block;
|
|
50
|
+
toBytes(): Uint8Array;
|
|
51
|
+
toJSON(): ReturnType<Header["toJSON"]> & {
|
|
52
|
+
tx: ReturnType<Tx["toJSON"]>[];
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export declare class TrimmedBlock {
|
|
56
|
+
readonly header: Header;
|
|
57
|
+
readonly transactions: H256[];
|
|
58
|
+
constructor(header: Header, transactions: H256[]);
|
|
59
|
+
marshalTo(writer: BinaryWriter): void;
|
|
60
|
+
static unmarshalFrom(reader: BinaryReader): TrimmedBlock;
|
|
61
|
+
toBytes(): Uint8Array;
|
|
62
|
+
toJSON(): ReturnType<Header["toJSON"]> & {
|
|
63
|
+
tx: string[];
|
|
64
|
+
};
|
|
65
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { encodeUInt32LE } from "../internal/bytes.js";
|
|
3
|
+
import { H160, H256 } from "./hash.js";
|
|
4
|
+
import { BinaryWriter, serialize } from "./serializing.js";
|
|
5
|
+
import { Tx } from "./tx.js";
|
|
6
|
+
import { Witness } from "./witness.js";
|
|
7
|
+
export class Header {
|
|
8
|
+
version;
|
|
9
|
+
previousBlockHash;
|
|
10
|
+
merkleRoot;
|
|
11
|
+
unixMillis;
|
|
12
|
+
nonce;
|
|
13
|
+
index;
|
|
14
|
+
primaryIndex;
|
|
15
|
+
nextConsensus;
|
|
16
|
+
witness;
|
|
17
|
+
constructor({ version, previousBlockHash, merkleRoot, unixMillis, nonce, index, primaryIndex, nextConsensus, witness, }) {
|
|
18
|
+
this.version = version;
|
|
19
|
+
this.previousBlockHash = previousBlockHash;
|
|
20
|
+
this.merkleRoot = merkleRoot;
|
|
21
|
+
this.unixMillis = BigInt(unixMillis);
|
|
22
|
+
this.nonce = nonce;
|
|
23
|
+
this.index = index;
|
|
24
|
+
this.primaryIndex = primaryIndex;
|
|
25
|
+
this.nextConsensus = nextConsensus;
|
|
26
|
+
this.witness = witness;
|
|
27
|
+
}
|
|
28
|
+
get time() {
|
|
29
|
+
return this.unixMillis;
|
|
30
|
+
}
|
|
31
|
+
getSignData(networkId) {
|
|
32
|
+
const writer = new BinaryWriter();
|
|
33
|
+
this.marshalUnsignedTo(writer);
|
|
34
|
+
const digest = createHash("sha256").update(writer.toBytes()).digest();
|
|
35
|
+
return new Uint8Array([...encodeUInt32LE(networkId), ...digest]);
|
|
36
|
+
}
|
|
37
|
+
marshalUnsignedTo(writer) {
|
|
38
|
+
writer.writeUInt32LE(this.version);
|
|
39
|
+
this.previousBlockHash.marshalTo(writer);
|
|
40
|
+
this.merkleRoot.marshalTo(writer);
|
|
41
|
+
writer.writeUInt64LE(this.unixMillis);
|
|
42
|
+
writer.writeUInt32LE(this.nonce);
|
|
43
|
+
writer.writeUInt32LE(this.index);
|
|
44
|
+
writer.writeUInt8(this.primaryIndex);
|
|
45
|
+
this.nextConsensus.marshalTo(writer);
|
|
46
|
+
}
|
|
47
|
+
marshalTo(writer) {
|
|
48
|
+
this.marshalUnsignedTo(writer);
|
|
49
|
+
this.witness.marshalTo(writer);
|
|
50
|
+
}
|
|
51
|
+
static unmarshalFrom(reader) {
|
|
52
|
+
return new Header({
|
|
53
|
+
version: reader.readUInt32LE(),
|
|
54
|
+
previousBlockHash: H256.unmarshalFrom(reader),
|
|
55
|
+
merkleRoot: H256.unmarshalFrom(reader),
|
|
56
|
+
unixMillis: reader.readUInt64LE(),
|
|
57
|
+
nonce: reader.readUInt32LE(),
|
|
58
|
+
index: reader.readUInt32LE(),
|
|
59
|
+
primaryIndex: reader.readUInt8(),
|
|
60
|
+
nextConsensus: H160.unmarshalFrom(reader),
|
|
61
|
+
witness: Witness.unmarshalFrom(reader),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
toBytes() {
|
|
65
|
+
return serialize(this);
|
|
66
|
+
}
|
|
67
|
+
toJSON() {
|
|
68
|
+
return {
|
|
69
|
+
version: this.version,
|
|
70
|
+
previousblockhash: this.previousBlockHash.toString(),
|
|
71
|
+
merkleroot: this.merkleRoot.toString(),
|
|
72
|
+
time: this.unixMillis.toString(),
|
|
73
|
+
nonce: this.nonce,
|
|
74
|
+
index: this.index,
|
|
75
|
+
primaryindex: this.primaryIndex,
|
|
76
|
+
nextconsensus: this.nextConsensus.toString(),
|
|
77
|
+
witness: this.witness.toJSON(),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
export class Block {
|
|
82
|
+
header;
|
|
83
|
+
transactions;
|
|
84
|
+
constructor(header, transactions) {
|
|
85
|
+
this.header = header;
|
|
86
|
+
this.transactions = transactions;
|
|
87
|
+
}
|
|
88
|
+
marshalTo(writer) {
|
|
89
|
+
this.header.marshalTo(writer);
|
|
90
|
+
writer.writeMultiple(this.transactions);
|
|
91
|
+
}
|
|
92
|
+
static unmarshalFrom(reader) {
|
|
93
|
+
return new Block(Header.unmarshalFrom(reader), reader.readMultiple(Tx));
|
|
94
|
+
}
|
|
95
|
+
toBytes() {
|
|
96
|
+
return serialize(this);
|
|
97
|
+
}
|
|
98
|
+
toJSON() {
|
|
99
|
+
return {
|
|
100
|
+
...this.header.toJSON(),
|
|
101
|
+
tx: this.transactions.map((transaction) => transaction.toJSON()),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
export class TrimmedBlock {
|
|
106
|
+
header;
|
|
107
|
+
transactions;
|
|
108
|
+
constructor(header, transactions) {
|
|
109
|
+
this.header = header;
|
|
110
|
+
this.transactions = transactions;
|
|
111
|
+
}
|
|
112
|
+
marshalTo(writer) {
|
|
113
|
+
this.header.marshalTo(writer);
|
|
114
|
+
writer.writeMultiple(this.transactions);
|
|
115
|
+
}
|
|
116
|
+
static unmarshalFrom(reader) {
|
|
117
|
+
return new TrimmedBlock(Header.unmarshalFrom(reader), reader.readMultiple(H256));
|
|
118
|
+
}
|
|
119
|
+
toBytes() {
|
|
120
|
+
return serialize(this);
|
|
121
|
+
}
|
|
122
|
+
toJSON() {
|
|
123
|
+
return {
|
|
124
|
+
...this.header.toJSON(),
|
|
125
|
+
tx: this.transactions.map((transaction) => transaction.toString()),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BytesLike } from "../internal/bytes.js";
|
|
2
|
+
import { BinaryReader, BinaryWriter } from "./serializing.js";
|
|
3
|
+
declare abstract class HashBase {
|
|
4
|
+
private readonly byteLength;
|
|
5
|
+
protected readonly data: Uint8Array;
|
|
6
|
+
protected constructor(byteLength: number, data: Uint8Array);
|
|
7
|
+
toBytes(): Uint8Array;
|
|
8
|
+
marshalTo(writer: BinaryWriter): void;
|
|
9
|
+
toString(): string;
|
|
10
|
+
equals(other: HashBase | string): boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class H160 extends HashBase {
|
|
13
|
+
constructor(value?: BytesLike | string);
|
|
14
|
+
static unmarshalFrom(reader: BinaryReader): H160;
|
|
15
|
+
}
|
|
16
|
+
export declare class H256 extends HashBase {
|
|
17
|
+
constructor(value?: BytesLike | string);
|
|
18
|
+
static unmarshalFrom(reader: BinaryReader): H256;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { bytesToHex, equalBytes, hexToBytes, reverseBytes, toUint8Array } from "../internal/bytes.js";
|
|
2
|
+
class HashBase {
|
|
3
|
+
byteLength;
|
|
4
|
+
data;
|
|
5
|
+
constructor(byteLength, data) {
|
|
6
|
+
this.byteLength = byteLength;
|
|
7
|
+
this.data = data;
|
|
8
|
+
if (data.length !== byteLength) {
|
|
9
|
+
throw new Error(`Hash must be ${byteLength} bytes`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
toBytes() {
|
|
13
|
+
return this.data.slice();
|
|
14
|
+
}
|
|
15
|
+
marshalTo(writer) {
|
|
16
|
+
writer.write(this.data);
|
|
17
|
+
}
|
|
18
|
+
toString() {
|
|
19
|
+
return `0x${bytesToHex(reverseBytes(this.data))}`;
|
|
20
|
+
}
|
|
21
|
+
equals(other) {
|
|
22
|
+
const comparable = typeof other === "string" ? new this.constructor(other) : other;
|
|
23
|
+
return equalBytes(this.data, comparable.data);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export class H160 extends HashBase {
|
|
27
|
+
constructor(value) {
|
|
28
|
+
const data = typeof value === "string"
|
|
29
|
+
? reverseBytes(hexToBytes(value))
|
|
30
|
+
: value === undefined
|
|
31
|
+
? new Uint8Array(20)
|
|
32
|
+
: toUint8Array(value);
|
|
33
|
+
super(20, data);
|
|
34
|
+
}
|
|
35
|
+
static unmarshalFrom(reader) {
|
|
36
|
+
return new H160(reader.read(20));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export class H256 extends HashBase {
|
|
40
|
+
constructor(value) {
|
|
41
|
+
const data = typeof value === "string"
|
|
42
|
+
? reverseBytes(hexToBytes(value))
|
|
43
|
+
: value === undefined
|
|
44
|
+
? new Uint8Array(32)
|
|
45
|
+
: toUint8Array(value);
|
|
46
|
+
super(32, data);
|
|
47
|
+
}
|
|
48
|
+
static unmarshalFrom(reader) {
|
|
49
|
+
return new H256(reader.read(32));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { H160 } from "./hash.js";
|
|
2
|
+
import { BinaryReader, BinaryWriter } from "./serializing.js";
|
|
3
|
+
import { Witness } from "./witness.js";
|
|
4
|
+
export declare class PrivateKey {
|
|
5
|
+
private readonly hex;
|
|
6
|
+
constructor(value?: Uint8Array | string | bigint | number);
|
|
7
|
+
publicKey(): PublicKey;
|
|
8
|
+
sign(message: Uint8Array): Uint8Array;
|
|
9
|
+
signWitness(signData: Uint8Array): Witness;
|
|
10
|
+
toBytes(): Uint8Array;
|
|
11
|
+
}
|
|
12
|
+
export declare class PublicKey {
|
|
13
|
+
private readonly hex;
|
|
14
|
+
constructor(value: Uint8Array | string);
|
|
15
|
+
getScriptHash(): H160;
|
|
16
|
+
getAddress(addressVersion?: number): string;
|
|
17
|
+
getSignatureRedeemScript(): Uint8Array;
|
|
18
|
+
verify(message: Uint8Array, signature: Uint8Array): boolean;
|
|
19
|
+
toBytes(): Uint8Array;
|
|
20
|
+
marshalTo(writer: BinaryWriter): void;
|
|
21
|
+
static unmarshalFrom(reader: BinaryReader): PublicKey;
|
|
22
|
+
toString(): string;
|
|
23
|
+
equals(other: PublicKey | string): boolean;
|
|
24
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { wallet } from "@cityofzion/neon-core";
|
|
2
|
+
import { randomBytes } from "node:crypto";
|
|
3
|
+
import { bytesToHex, equalBytes, hexToBytes, toUint8Array } from "../internal/bytes.js";
|
|
4
|
+
import { H160 } from "./hash.js";
|
|
5
|
+
import { ScriptBuilder } from "./script.js";
|
|
6
|
+
import { Witness } from "./witness.js";
|
|
7
|
+
function privateKeyToHex(value) {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
const bytes = hexToBytes(value);
|
|
10
|
+
if (bytes.length !== 32) {
|
|
11
|
+
throw new Error("invalid secp256r1 private key");
|
|
12
|
+
}
|
|
13
|
+
return bytesToHex(bytes);
|
|
14
|
+
}
|
|
15
|
+
if (typeof value === "bigint" || typeof value === "number") {
|
|
16
|
+
let remaining = BigInt(value);
|
|
17
|
+
const bytes = new Uint8Array(32);
|
|
18
|
+
for (let index = 31; index >= 0; index -= 1) {
|
|
19
|
+
bytes[index] = Number(remaining & 0xffn);
|
|
20
|
+
remaining >>= 8n;
|
|
21
|
+
}
|
|
22
|
+
return bytesToHex(bytes);
|
|
23
|
+
}
|
|
24
|
+
if (value instanceof Uint8Array) {
|
|
25
|
+
if (value.length !== 32) {
|
|
26
|
+
throw new Error("invalid secp256r1 private key");
|
|
27
|
+
}
|
|
28
|
+
return bytesToHex(value);
|
|
29
|
+
}
|
|
30
|
+
return bytesToHex(randomBytes(32));
|
|
31
|
+
}
|
|
32
|
+
export class PrivateKey {
|
|
33
|
+
hex;
|
|
34
|
+
constructor(value) {
|
|
35
|
+
this.hex = privateKeyToHex(value);
|
|
36
|
+
}
|
|
37
|
+
publicKey() {
|
|
38
|
+
return new PublicKey(wallet.getPublicKeyFromPrivateKey(this.hex));
|
|
39
|
+
}
|
|
40
|
+
sign(message) {
|
|
41
|
+
return hexToBytes(wallet.sign(bytesToHex(message), this.hex));
|
|
42
|
+
}
|
|
43
|
+
signWitness(signData) {
|
|
44
|
+
const signature = this.sign(signData);
|
|
45
|
+
const invocation = new ScriptBuilder().emitPush(signature).toBytes();
|
|
46
|
+
const verification = this.publicKey().getSignatureRedeemScript();
|
|
47
|
+
return new Witness(invocation, verification);
|
|
48
|
+
}
|
|
49
|
+
toBytes() {
|
|
50
|
+
return hexToBytes(this.hex);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export class PublicKey {
|
|
54
|
+
hex;
|
|
55
|
+
constructor(value) {
|
|
56
|
+
const bytes = typeof value === "string" ? hexToBytes(value) : toUint8Array(value);
|
|
57
|
+
if (![33, 65].includes(bytes.length)) {
|
|
58
|
+
throw new Error("unsupported public key");
|
|
59
|
+
}
|
|
60
|
+
this.hex = bytesToHex(bytes);
|
|
61
|
+
}
|
|
62
|
+
getScriptHash() {
|
|
63
|
+
return new H160(`0x${wallet.getScriptHashFromPublicKey(this.hex)}`);
|
|
64
|
+
}
|
|
65
|
+
getAddress(addressVersion = 53) {
|
|
66
|
+
return wallet.getAddressFromScriptHash(wallet.getScriptHashFromPublicKey(this.hex), addressVersion);
|
|
67
|
+
}
|
|
68
|
+
getSignatureRedeemScript() {
|
|
69
|
+
return hexToBytes(wallet.getVerificationScriptFromPublicKey(this.hex));
|
|
70
|
+
}
|
|
71
|
+
verify(message, signature) {
|
|
72
|
+
return wallet.verify(bytesToHex(message), bytesToHex(signature), this.hex);
|
|
73
|
+
}
|
|
74
|
+
toBytes() {
|
|
75
|
+
return hexToBytes(this.hex);
|
|
76
|
+
}
|
|
77
|
+
marshalTo(writer) {
|
|
78
|
+
writer.write(this.toBytes());
|
|
79
|
+
}
|
|
80
|
+
static unmarshalFrom(reader) {
|
|
81
|
+
const prefix = reader.readUInt8();
|
|
82
|
+
if (prefix === 0x02 || prefix === 0x03) {
|
|
83
|
+
return new PublicKey(Uint8Array.of(prefix, ...reader.read(32)));
|
|
84
|
+
}
|
|
85
|
+
if (prefix === 0x04) {
|
|
86
|
+
return new PublicKey(Uint8Array.of(prefix, ...reader.read(64)));
|
|
87
|
+
}
|
|
88
|
+
throw new Error(`unexpected PublicKey prefix: ${prefix}`);
|
|
89
|
+
}
|
|
90
|
+
toString() {
|
|
91
|
+
return this.hex;
|
|
92
|
+
}
|
|
93
|
+
equals(other) {
|
|
94
|
+
const comparable = typeof other === "string" ? new PublicKey(other) : other;
|
|
95
|
+
return equalBytes(this.toBytes(), comparable.toBytes());
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { H160 } from "./hash.js";
|
|
2
|
+
import { OpCode } from "./opcode.js";
|
|
3
|
+
export declare enum CallFlags {
|
|
4
|
+
NONE = 0,
|
|
5
|
+
ReadStates = 1,
|
|
6
|
+
WriteStates = 2,
|
|
7
|
+
AllowCall = 4,
|
|
8
|
+
AllowNotify = 8,
|
|
9
|
+
States = 3,
|
|
10
|
+
ReadOnly = 5,
|
|
11
|
+
All = 15
|
|
12
|
+
}
|
|
13
|
+
export declare function syscallCode(syscallName: string): number;
|
|
14
|
+
export declare class ScriptBuilder {
|
|
15
|
+
private readonly script;
|
|
16
|
+
emit(opcode: OpCode, operand?: Uint8Array): this;
|
|
17
|
+
emitPush(item: unknown): this;
|
|
18
|
+
private emitPushInt;
|
|
19
|
+
private emitPushBytes;
|
|
20
|
+
private emitPushArray;
|
|
21
|
+
emitContractCall(contractHash: H160 | string, method: string, callFlags?: CallFlags, args?: unknown[]): this;
|
|
22
|
+
emitSyscall(syscall: number | string, args?: unknown[]): this;
|
|
23
|
+
toBytes(): Uint8Array;
|
|
24
|
+
toHex(): string;
|
|
25
|
+
}
|