@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
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PrivateKey } from "../core/keypair.js";
|
|
2
|
+
export declare class ScryptParams {
|
|
3
|
+
readonly n: number;
|
|
4
|
+
readonly r: number;
|
|
5
|
+
readonly p: number;
|
|
6
|
+
constructor(n?: number, r?: number, p?: number);
|
|
7
|
+
toJSON(): {
|
|
8
|
+
n: number;
|
|
9
|
+
r: number;
|
|
10
|
+
p: number;
|
|
11
|
+
};
|
|
12
|
+
static fromJSON(data: {
|
|
13
|
+
n: number;
|
|
14
|
+
r: number;
|
|
15
|
+
p: number;
|
|
16
|
+
}): ScryptParams;
|
|
17
|
+
}
|
|
18
|
+
export declare function encryptSecp256r1Key(privateKey: PrivateKey, passphrase: string, addressVersion?: number, scrypt?: ScryptParams): string;
|
|
19
|
+
export declare function decryptSecp256r1Key(key: string, passphrase: string, addressVersion?: number, scrypt?: ScryptParams): PrivateKey;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, createHash, scryptSync } from "node:crypto";
|
|
2
|
+
import bs58 from "bs58";
|
|
3
|
+
import { PrivateKey } from "../core/keypair.js";
|
|
4
|
+
/** NEP-2 encrypted key prefix: 0x01 0x42 0xe0 (flag byte = 0xe0 for secp256r1) */
|
|
5
|
+
const NEP2_PREFIX = Buffer.from([0x01, 0x42, 0xe0]);
|
|
6
|
+
export class ScryptParams {
|
|
7
|
+
n;
|
|
8
|
+
r;
|
|
9
|
+
p;
|
|
10
|
+
constructor(n = 16384, r = 8, p = 8) {
|
|
11
|
+
this.n = n;
|
|
12
|
+
this.r = r;
|
|
13
|
+
this.p = p;
|
|
14
|
+
}
|
|
15
|
+
toJSON() {
|
|
16
|
+
return { n: this.n, r: this.r, p: this.p };
|
|
17
|
+
}
|
|
18
|
+
static fromJSON(data) {
|
|
19
|
+
return new ScryptParams(data.n, data.r, data.p);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function addressHash(address) {
|
|
23
|
+
const first = createHash("sha256").update(address, "utf8").digest();
|
|
24
|
+
return createHash("sha256").update(first).digest().subarray(0, 4);
|
|
25
|
+
}
|
|
26
|
+
function computeChecksum(payload) {
|
|
27
|
+
return createHash("sha256").update(createHash("sha256").update(payload).digest()).digest().subarray(0, 4);
|
|
28
|
+
}
|
|
29
|
+
function base58CheckEncode(payload) {
|
|
30
|
+
const checksum = computeChecksum(payload);
|
|
31
|
+
return bs58.encode(Buffer.concat([Buffer.from(payload), checksum]));
|
|
32
|
+
}
|
|
33
|
+
function base58CheckDecode(value) {
|
|
34
|
+
const decoded = Buffer.from(bs58.decode(value));
|
|
35
|
+
if (decoded.length < 5) {
|
|
36
|
+
throw new Error("NEP-2: invalid base58check key");
|
|
37
|
+
}
|
|
38
|
+
const payload = decoded.subarray(0, -4);
|
|
39
|
+
const checksum = decoded.subarray(-4);
|
|
40
|
+
if (!checksum.equals(computeChecksum(payload))) {
|
|
41
|
+
throw new Error("NEP-2: invalid base58check checksum");
|
|
42
|
+
}
|
|
43
|
+
return payload;
|
|
44
|
+
}
|
|
45
|
+
function deriveKey(passphrase, salt, scrypt) {
|
|
46
|
+
return scryptSync(passphrase.normalize("NFC"), salt, 64, {
|
|
47
|
+
N: scrypt.n,
|
|
48
|
+
r: scrypt.r,
|
|
49
|
+
p: scrypt.p,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function encryptAesEcb(key, value) {
|
|
53
|
+
const cipher = createCipheriv("aes-256-ecb", key, null);
|
|
54
|
+
cipher.setAutoPadding(false);
|
|
55
|
+
return Buffer.concat([cipher.update(value), cipher.final()]);
|
|
56
|
+
}
|
|
57
|
+
function decryptAesEcb(key, value) {
|
|
58
|
+
const decipher = createDecipheriv("aes-256-ecb", key, null);
|
|
59
|
+
decipher.setAutoPadding(false);
|
|
60
|
+
return Buffer.concat([decipher.update(value), decipher.final()]);
|
|
61
|
+
}
|
|
62
|
+
export function encryptSecp256r1Key(privateKey, passphrase, addressVersion = 53, scrypt = new ScryptParams()) {
|
|
63
|
+
const checksum = addressHash(privateKey.publicKey().getAddress(addressVersion));
|
|
64
|
+
const derived = deriveKey(passphrase, checksum, scrypt);
|
|
65
|
+
const secretBytes = Buffer.from(privateKey.toBytes());
|
|
66
|
+
const xor = Buffer.allocUnsafe(32);
|
|
67
|
+
for (let index = 0; index < 32; index += 1) {
|
|
68
|
+
xor[index] = secretBytes[index] ^ derived[index];
|
|
69
|
+
}
|
|
70
|
+
const encrypted = encryptAesEcb(derived.subarray(32), xor);
|
|
71
|
+
const payload = Buffer.concat([NEP2_PREFIX, checksum, encrypted]);
|
|
72
|
+
return base58CheckEncode(payload);
|
|
73
|
+
}
|
|
74
|
+
export function decryptSecp256r1Key(key, passphrase, addressVersion = 53, scrypt = new ScryptParams()) {
|
|
75
|
+
const payload = base58CheckDecode(key);
|
|
76
|
+
if (payload.length !== 39) {
|
|
77
|
+
throw new Error("NEP-2 key must be 39 bytes");
|
|
78
|
+
}
|
|
79
|
+
if (!payload.subarray(0, 3).equals(NEP2_PREFIX)) {
|
|
80
|
+
throw new Error("NEP-2 key has invalid prefix");
|
|
81
|
+
}
|
|
82
|
+
const checksum = payload.subarray(3, 7);
|
|
83
|
+
const encrypted = payload.subarray(7);
|
|
84
|
+
const derived = deriveKey(passphrase, checksum, scrypt);
|
|
85
|
+
const decrypted = decryptAesEcb(derived.subarray(32), encrypted);
|
|
86
|
+
const secretBytes = Buffer.allocUnsafe(32);
|
|
87
|
+
for (let index = 0; index < 32; index += 1) {
|
|
88
|
+
secretBytes[index] = decrypted[index] ^ derived[index];
|
|
89
|
+
}
|
|
90
|
+
const privateKey = new PrivateKey(secretBytes);
|
|
91
|
+
const address = privateKey.publicKey().getAddress(addressVersion);
|
|
92
|
+
if (!addressHash(address).equals(checksum)) {
|
|
93
|
+
throw new Error("NEP-2 checksum mismatch");
|
|
94
|
+
}
|
|
95
|
+
return privateKey;
|
|
96
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { H160 } from "../core/hash.js";
|
|
2
|
+
import { PrivateKey, PublicKey } from "../core/keypair.js";
|
|
3
|
+
import { Witness } from "../core/witness.js";
|
|
4
|
+
import { ScryptParams } from "./nep2.js";
|
|
5
|
+
export declare class Parameter {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly type: string;
|
|
8
|
+
constructor(name: string, type: string);
|
|
9
|
+
toJSON(): {
|
|
10
|
+
name: string;
|
|
11
|
+
type: string;
|
|
12
|
+
};
|
|
13
|
+
static fromJSON(data: {
|
|
14
|
+
name: string;
|
|
15
|
+
type: string;
|
|
16
|
+
}): Parameter;
|
|
17
|
+
}
|
|
18
|
+
export declare class Contract {
|
|
19
|
+
readonly script: Uint8Array;
|
|
20
|
+
readonly parameters: Parameter[];
|
|
21
|
+
readonly deployed: boolean;
|
|
22
|
+
constructor(script: Uint8Array, parameters: Parameter[], deployed?: boolean);
|
|
23
|
+
toJSON(): {
|
|
24
|
+
script: string;
|
|
25
|
+
parameters: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
type: string;
|
|
28
|
+
}>;
|
|
29
|
+
deployed: boolean;
|
|
30
|
+
};
|
|
31
|
+
static fromJSON(data: {
|
|
32
|
+
script: string;
|
|
33
|
+
parameters: Array<{
|
|
34
|
+
name: string;
|
|
35
|
+
type: string;
|
|
36
|
+
}>;
|
|
37
|
+
deployed: boolean;
|
|
38
|
+
}): Contract;
|
|
39
|
+
}
|
|
40
|
+
export interface AccountOptions {
|
|
41
|
+
address: string;
|
|
42
|
+
key: string;
|
|
43
|
+
contract: Contract | null;
|
|
44
|
+
label?: string;
|
|
45
|
+
isDefault?: boolean;
|
|
46
|
+
locked?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export declare class Account {
|
|
49
|
+
private privateKey;
|
|
50
|
+
readonly address: string;
|
|
51
|
+
readonly key: string;
|
|
52
|
+
readonly contract: Contract | null;
|
|
53
|
+
readonly label: string;
|
|
54
|
+
readonly isDefault: boolean;
|
|
55
|
+
readonly locked: boolean;
|
|
56
|
+
constructor({ address, key, contract, label, isDefault, locked }: AccountOptions);
|
|
57
|
+
setPrivateKey(privateKey: PrivateKey): void;
|
|
58
|
+
watchOnly(): boolean;
|
|
59
|
+
decrypt(passphrase: string, addressVersion?: number, scrypt?: ScryptParams): PublicKey;
|
|
60
|
+
signable(): boolean;
|
|
61
|
+
sign(message: Uint8Array): Uint8Array;
|
|
62
|
+
signWitness(signData: Uint8Array): Witness;
|
|
63
|
+
getScriptHash(): H160;
|
|
64
|
+
toJSON(): {
|
|
65
|
+
address: string;
|
|
66
|
+
key: string;
|
|
67
|
+
label: string;
|
|
68
|
+
isDefault: boolean;
|
|
69
|
+
lock: boolean;
|
|
70
|
+
contract: ReturnType<Contract["toJSON"]> | null;
|
|
71
|
+
};
|
|
72
|
+
static fromJSON(data: {
|
|
73
|
+
address: string;
|
|
74
|
+
key: string;
|
|
75
|
+
label: string;
|
|
76
|
+
isDefault: boolean;
|
|
77
|
+
lock: boolean;
|
|
78
|
+
contract: {
|
|
79
|
+
script: string;
|
|
80
|
+
parameters: Array<{
|
|
81
|
+
name: string;
|
|
82
|
+
type: string;
|
|
83
|
+
}>;
|
|
84
|
+
deployed: boolean;
|
|
85
|
+
} | null;
|
|
86
|
+
}): Account;
|
|
87
|
+
}
|
|
88
|
+
export interface WalletOptions {
|
|
89
|
+
name: string;
|
|
90
|
+
accounts?: Account[];
|
|
91
|
+
scrypt?: ScryptParams;
|
|
92
|
+
passphrase?: string;
|
|
93
|
+
version?: string;
|
|
94
|
+
}
|
|
95
|
+
export declare class Wallet {
|
|
96
|
+
readonly name: string;
|
|
97
|
+
readonly version: string;
|
|
98
|
+
readonly scrypt: ScryptParams;
|
|
99
|
+
readonly accounts: Account[];
|
|
100
|
+
private passphrase?;
|
|
101
|
+
constructor({ name, accounts, scrypt, passphrase, version }: WalletOptions);
|
|
102
|
+
createAccount(): Account;
|
|
103
|
+
decrypt(passphrase: string): void;
|
|
104
|
+
writeToFile(path: string): void;
|
|
105
|
+
toJSON(): {
|
|
106
|
+
name: string;
|
|
107
|
+
version: string;
|
|
108
|
+
scrypt: ReturnType<ScryptParams["toJSON"]>;
|
|
109
|
+
accounts: ReturnType<Account["toJSON"]>[];
|
|
110
|
+
};
|
|
111
|
+
static fromJSON(data: {
|
|
112
|
+
name: string;
|
|
113
|
+
version: string;
|
|
114
|
+
scrypt: {
|
|
115
|
+
n: number;
|
|
116
|
+
r: number;
|
|
117
|
+
p: number;
|
|
118
|
+
};
|
|
119
|
+
accounts: Array<{
|
|
120
|
+
address: string;
|
|
121
|
+
key: string;
|
|
122
|
+
label: string;
|
|
123
|
+
isDefault: boolean;
|
|
124
|
+
lock: boolean;
|
|
125
|
+
contract: {
|
|
126
|
+
script: string;
|
|
127
|
+
parameters: Array<{
|
|
128
|
+
name: string;
|
|
129
|
+
type: string;
|
|
130
|
+
}>;
|
|
131
|
+
deployed: boolean;
|
|
132
|
+
} | null;
|
|
133
|
+
}>;
|
|
134
|
+
}): Wallet;
|
|
135
|
+
static openNep6Wallet(path: string): Wallet;
|
|
136
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { wallet as neonWallet } from "@cityofzion/neon-core";
|
|
3
|
+
import { base64ToBytes, bytesToBase64 } from "../internal/bytes.js";
|
|
4
|
+
import { H160 } from "../core/hash.js";
|
|
5
|
+
import { PrivateKey } from "../core/keypair.js";
|
|
6
|
+
import { ScryptParams, decryptSecp256r1Key, encryptSecp256r1Key } from "./nep2.js";
|
|
7
|
+
export class Parameter {
|
|
8
|
+
name;
|
|
9
|
+
type;
|
|
10
|
+
constructor(name, type) {
|
|
11
|
+
this.name = name;
|
|
12
|
+
this.type = type;
|
|
13
|
+
}
|
|
14
|
+
toJSON() {
|
|
15
|
+
return { name: this.name, type: this.type };
|
|
16
|
+
}
|
|
17
|
+
static fromJSON(data) {
|
|
18
|
+
return new Parameter(data.name, data.type);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export class Contract {
|
|
22
|
+
script;
|
|
23
|
+
parameters;
|
|
24
|
+
deployed;
|
|
25
|
+
constructor(script, parameters, deployed = false) {
|
|
26
|
+
this.script = script;
|
|
27
|
+
this.parameters = parameters;
|
|
28
|
+
this.deployed = deployed;
|
|
29
|
+
}
|
|
30
|
+
toJSON() {
|
|
31
|
+
return {
|
|
32
|
+
script: bytesToBase64(this.script),
|
|
33
|
+
parameters: this.parameters.map((parameter) => parameter.toJSON()),
|
|
34
|
+
deployed: this.deployed,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
static fromJSON(data) {
|
|
38
|
+
return new Contract(base64ToBytes(data.script), data.parameters.map((parameter) => Parameter.fromJSON(parameter)), data.deployed);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export class Account {
|
|
42
|
+
privateKey = null;
|
|
43
|
+
address;
|
|
44
|
+
key;
|
|
45
|
+
contract;
|
|
46
|
+
label;
|
|
47
|
+
isDefault;
|
|
48
|
+
locked;
|
|
49
|
+
constructor({ address, key, contract, label = "", isDefault = false, locked = false }) {
|
|
50
|
+
this.address = address;
|
|
51
|
+
this.key = key;
|
|
52
|
+
this.contract = contract;
|
|
53
|
+
this.label = label;
|
|
54
|
+
this.isDefault = isDefault;
|
|
55
|
+
this.locked = locked;
|
|
56
|
+
}
|
|
57
|
+
setPrivateKey(privateKey) {
|
|
58
|
+
this.privateKey = privateKey;
|
|
59
|
+
}
|
|
60
|
+
watchOnly() {
|
|
61
|
+
return this.contract === null;
|
|
62
|
+
}
|
|
63
|
+
decrypt(passphrase, addressVersion = 53, scrypt = new ScryptParams()) {
|
|
64
|
+
this.privateKey = decryptSecp256r1Key(this.key, passphrase, addressVersion, scrypt);
|
|
65
|
+
return this.privateKey.publicKey();
|
|
66
|
+
}
|
|
67
|
+
signable() {
|
|
68
|
+
return this.privateKey !== null && !this.locked && !this.watchOnly();
|
|
69
|
+
}
|
|
70
|
+
sign(message) {
|
|
71
|
+
if (this.privateKey === null) {
|
|
72
|
+
throw new Error("account is locked");
|
|
73
|
+
}
|
|
74
|
+
return this.privateKey.sign(message);
|
|
75
|
+
}
|
|
76
|
+
signWitness(signData) {
|
|
77
|
+
if (this.privateKey === null) {
|
|
78
|
+
throw new Error("account is locked");
|
|
79
|
+
}
|
|
80
|
+
return this.privateKey.signWitness(signData);
|
|
81
|
+
}
|
|
82
|
+
getScriptHash() {
|
|
83
|
+
if (this.privateKey !== null) {
|
|
84
|
+
return this.privateKey.publicKey().getScriptHash();
|
|
85
|
+
}
|
|
86
|
+
return new H160(`0x${neonWallet.getScriptHashFromAddress(this.address)}`);
|
|
87
|
+
}
|
|
88
|
+
toJSON() {
|
|
89
|
+
if (this.contract === null) {
|
|
90
|
+
throw new Error("neo: watch-only account cannot be serialized to NEP-6 by this compatibility layer");
|
|
91
|
+
}
|
|
92
|
+
return {
|
|
93
|
+
address: this.address,
|
|
94
|
+
key: this.key,
|
|
95
|
+
label: this.label,
|
|
96
|
+
isDefault: this.isDefault,
|
|
97
|
+
lock: this.locked,
|
|
98
|
+
contract: this.contract.toJSON(),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
static fromJSON(data) {
|
|
102
|
+
if (data.contract === null || data.contract === undefined) {
|
|
103
|
+
throw new Error("contract is required in NEP-6 JSON");
|
|
104
|
+
}
|
|
105
|
+
return new Account({
|
|
106
|
+
address: data.address,
|
|
107
|
+
key: data.key,
|
|
108
|
+
label: data.label,
|
|
109
|
+
isDefault: data.isDefault,
|
|
110
|
+
locked: data.lock,
|
|
111
|
+
contract: Contract.fromJSON(data.contract),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export class Wallet {
|
|
116
|
+
name;
|
|
117
|
+
version;
|
|
118
|
+
scrypt;
|
|
119
|
+
accounts;
|
|
120
|
+
passphrase;
|
|
121
|
+
constructor({ name, accounts = [], scrypt = new ScryptParams(), passphrase, version = "1.0" }) {
|
|
122
|
+
this.name = name;
|
|
123
|
+
this.accounts = accounts;
|
|
124
|
+
this.scrypt = scrypt;
|
|
125
|
+
this.version = version;
|
|
126
|
+
this.passphrase = passphrase;
|
|
127
|
+
}
|
|
128
|
+
createAccount() {
|
|
129
|
+
if (!this.passphrase) {
|
|
130
|
+
throw new Error("passphrase is not set");
|
|
131
|
+
}
|
|
132
|
+
const privateKey = new PrivateKey();
|
|
133
|
+
const publicKey = privateKey.publicKey();
|
|
134
|
+
const address = publicKey.getAddress();
|
|
135
|
+
const contract = new Contract(publicKey.getSignatureRedeemScript(), [new Parameter("signature", "Signature")]);
|
|
136
|
+
const key = encryptSecp256r1Key(privateKey, this.passphrase, 53, this.scrypt);
|
|
137
|
+
const account = new Account({
|
|
138
|
+
address,
|
|
139
|
+
key,
|
|
140
|
+
contract,
|
|
141
|
+
});
|
|
142
|
+
account.setPrivateKey(privateKey);
|
|
143
|
+
this.accounts.push(account);
|
|
144
|
+
return account;
|
|
145
|
+
}
|
|
146
|
+
decrypt(passphrase) {
|
|
147
|
+
this.passphrase = passphrase;
|
|
148
|
+
for (const account of this.accounts) {
|
|
149
|
+
account.decrypt(passphrase, 53, this.scrypt);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
writeToFile(path) {
|
|
153
|
+
if (existsSync(path)) {
|
|
154
|
+
throw new Error(`wallet file ${path} already exists`);
|
|
155
|
+
}
|
|
156
|
+
writeFileSync(path, JSON.stringify(this.toJSON()), "utf8");
|
|
157
|
+
}
|
|
158
|
+
toJSON() {
|
|
159
|
+
return {
|
|
160
|
+
name: this.name,
|
|
161
|
+
version: this.version,
|
|
162
|
+
scrypt: this.scrypt.toJSON(),
|
|
163
|
+
accounts: this.accounts.map((account) => account.toJSON()),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
static fromJSON(data) {
|
|
167
|
+
return new Wallet({
|
|
168
|
+
name: data.name,
|
|
169
|
+
version: data.version,
|
|
170
|
+
scrypt: ScryptParams.fromJSON(data.scrypt),
|
|
171
|
+
accounts: data.accounts.map((account) => Account.fromJSON(account)),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
static openNep6Wallet(path) {
|
|
175
|
+
const raw = readFileSync(path, "utf8");
|
|
176
|
+
return Wallet.fromJSON(JSON.parse(raw));
|
|
177
|
+
}
|
|
178
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@r3e/neo-js-sdk",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Neo N3 JavaScript/TypeScript SDK — successor to neo-js (no longer maintained). Typed models, object-based RPC inputs, full N3 RPC coverage.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/r3e-network/neo-js-sdk.git"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/r3e-network/neo-js-sdk#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/r3e-network/neo-js-sdk/issues"
|
|
12
|
+
},
|
|
13
|
+
"sideEffects": false,
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"type": "module",
|
|
21
|
+
"main": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"default": "./dist/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsc -p tsconfig.json",
|
|
34
|
+
"coverage": "vitest run --coverage.enabled true --coverage.provider v8 --coverage.reporter=text --coverage.reporter=json-summary",
|
|
35
|
+
"test": "vitest run",
|
|
36
|
+
"test:watch": "vitest",
|
|
37
|
+
"typecheck": "tsc -p tsconfig.typecheck.json",
|
|
38
|
+
"test:integration": "RUN_NEO_LIVE=1 vitest run tests/integration/rpc-live.test.ts",
|
|
39
|
+
"test:integration:wif": "RUN_NEO_LIVE=1 vitest run tests/integration/rpc-live-wif.test.ts"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"neo",
|
|
43
|
+
"neo-n3",
|
|
44
|
+
"neo-js",
|
|
45
|
+
"sdk",
|
|
46
|
+
"javascript",
|
|
47
|
+
"typescript",
|
|
48
|
+
"blockchain",
|
|
49
|
+
"n3"
|
|
50
|
+
],
|
|
51
|
+
"license": "MIT",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@cityofzion/neon-core": "^5.8.1",
|
|
54
|
+
"bs58": "^6.0.0"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/node": "^24.5.2",
|
|
58
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
59
|
+
"typescript": "^5.9.2",
|
|
60
|
+
"vitest": "^3.2.4"
|
|
61
|
+
}
|
|
62
|
+
}
|