near-kit 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +371 -2
- package/dist/contracts/contract.d.ts +63 -0
- package/dist/contracts/contract.d.ts.map +1 -0
- package/dist/contracts/contract.js +42 -0
- package/dist/contracts/contract.js.map +1 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.d.ts.map +1 -0
- package/dist/contracts/index.js +5 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/core/actions.d.ts +193 -0
- package/dist/core/actions.d.ts.map +1 -0
- package/dist/core/actions.js +195 -0
- package/dist/core/actions.js.map +1 -0
- package/dist/core/config-schemas.d.ts +179 -0
- package/dist/core/config-schemas.d.ts.map +1 -0
- package/dist/core/config-schemas.js +169 -0
- package/dist/core/config-schemas.js.map +1 -0
- package/dist/core/constants.d.ts +43 -0
- package/dist/core/constants.d.ts.map +1 -0
- package/dist/core/constants.js +49 -0
- package/dist/core/constants.js.map +1 -0
- package/dist/core/near.d.ts +301 -0
- package/dist/core/near.d.ts.map +1 -0
- package/dist/core/near.js +504 -0
- package/dist/core/near.js.map +1 -0
- package/dist/core/nonce-manager.d.ts +39 -0
- package/dist/core/nonce-manager.d.ts.map +1 -0
- package/dist/core/nonce-manager.js +73 -0
- package/dist/core/nonce-manager.js.map +1 -0
- package/dist/core/rpc/rpc-error-handler.d.ts +60 -0
- package/dist/core/rpc/rpc-error-handler.d.ts.map +1 -0
- package/dist/core/rpc/rpc-error-handler.js +324 -0
- package/dist/core/rpc/rpc-error-handler.js.map +1 -0
- package/dist/core/rpc/rpc-schemas.d.ts +1812 -0
- package/dist/core/rpc/rpc-schemas.d.ts.map +1 -0
- package/dist/core/rpc/rpc-schemas.js +424 -0
- package/dist/core/rpc/rpc-schemas.js.map +1 -0
- package/dist/core/rpc/rpc.d.ts +117 -0
- package/dist/core/rpc/rpc.d.ts.map +1 -0
- package/dist/core/rpc/rpc.js +325 -0
- package/dist/core/rpc/rpc.js.map +1 -0
- package/dist/core/schema.d.ts +1188 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +396 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/transaction.d.ts +390 -0
- package/dist/core/transaction.d.ts.map +1 -0
- package/dist/core/transaction.js +649 -0
- package/dist/core/transaction.js.map +1 -0
- package/dist/core/types.d.ts +271 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +9 -0
- package/dist/core/types.js.map +1 -0
- package/dist/errors/index.d.ts +226 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +366 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/keys/credential-schemas.d.ts +98 -0
- package/dist/keys/credential-schemas.d.ts.map +1 -0
- package/dist/keys/credential-schemas.js +128 -0
- package/dist/keys/credential-schemas.js.map +1 -0
- package/dist/keys/file-keystore.d.ts +130 -0
- package/dist/keys/file-keystore.d.ts.map +1 -0
- package/dist/keys/file-keystore.js +266 -0
- package/dist/keys/file-keystore.js.map +1 -0
- package/dist/keys/in-memory-keystore.d.ts +71 -0
- package/dist/keys/in-memory-keystore.d.ts.map +1 -0
- package/dist/keys/in-memory-keystore.js +85 -0
- package/dist/keys/in-memory-keystore.js.map +1 -0
- package/dist/keys/index.d.ts +12 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/index.js +18 -0
- package/dist/keys/index.js.map +1 -0
- package/dist/keys/native-keystore.d.ts +111 -0
- package/dist/keys/native-keystore.d.ts.map +1 -0
- package/dist/keys/native-keystore.js +167 -0
- package/dist/keys/native-keystore.js.map +1 -0
- package/dist/sandbox/index.d.ts +6 -0
- package/dist/sandbox/index.d.ts.map +1 -0
- package/dist/sandbox/index.js +5 -0
- package/dist/sandbox/index.js.map +1 -0
- package/dist/sandbox/sandbox.d.ts +55 -0
- package/dist/sandbox/sandbox.d.ts.map +1 -0
- package/dist/sandbox/sandbox.js +341 -0
- package/dist/sandbox/sandbox.js.map +1 -0
- package/dist/utils/amount.d.ts +76 -0
- package/dist/utils/amount.d.ts.map +1 -0
- package/dist/utils/amount.js +137 -0
- package/dist/utils/amount.js.map +1 -0
- package/dist/utils/gas.d.ts +69 -0
- package/dist/utils/gas.d.ts.map +1 -0
- package/dist/utils/gas.js +92 -0
- package/dist/utils/gas.js.map +1 -0
- package/dist/utils/index.d.ts +14 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +14 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/key.d.ts +117 -0
- package/dist/utils/key.d.ts.map +1 -0
- package/dist/utils/key.js +270 -0
- package/dist/utils/key.js.map +1 -0
- package/dist/utils/nep413.d.ts +97 -0
- package/dist/utils/nep413.d.ts.map +1 -0
- package/dist/utils/nep413.js +154 -0
- package/dist/utils/nep413.js.map +1 -0
- package/dist/utils/validation.d.ts +114 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +150 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/wallets/adapters.d.ts +119 -0
- package/dist/wallets/adapters.d.ts.map +1 -0
- package/dist/wallets/adapters.js +267 -0
- package/dist/wallets/adapters.js.map +1 -0
- package/dist/wallets/index.d.ts +11 -0
- package/dist/wallets/index.d.ts.map +1 -0
- package/dist/wallets/index.js +2 -0
- package/dist/wallets/index.js.map +1 -0
- package/dist/wallets/types.d.ts +99 -0
- package/dist/wallets/types.d.ts.map +1 -0
- package/dist/wallets/types.js +10 -0
- package/dist/wallets/types.js.map +1 -0
- package/package.json +78 -7
- package/index.js +0 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gas utilities for NEAR transactions.
|
|
3
|
+
*
|
|
4
|
+
* Gas amounts should specify units explicitly:
|
|
5
|
+
* - `Gas.Tgas(30)` → `"30 Tgas"`
|
|
6
|
+
* - `"30 Tgas"` (string literal)
|
|
7
|
+
*
|
|
8
|
+
* Raw gas units (e.g. `"30000000000000"`) are also supported for advanced use cases.
|
|
9
|
+
*/
|
|
10
|
+
import { GAS_PER_TGAS } from "../core/constants.js";
|
|
11
|
+
/**
|
|
12
|
+
* Gas namespace - explicit constructors.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* Gas.Tgas(30) // "30 Tgas"
|
|
16
|
+
* Gas.Tgas(300) // "300 Tgas"
|
|
17
|
+
*/
|
|
18
|
+
export const Gas = {
|
|
19
|
+
/**
|
|
20
|
+
* Create gas amount in TGas (teragas).
|
|
21
|
+
* @param value - Amount in TGas.
|
|
22
|
+
*/
|
|
23
|
+
Tgas(value) {
|
|
24
|
+
return `${value} Tgas`;
|
|
25
|
+
},
|
|
26
|
+
/**
|
|
27
|
+
* Common gas amounts.
|
|
28
|
+
*/
|
|
29
|
+
DEFAULT: "30 Tgas",
|
|
30
|
+
MAX: "300 Tgas",
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Parse gas string to raw gas units.
|
|
34
|
+
*
|
|
35
|
+
* @param gas - Gas with unit (e.g., `"30 Tgas"`) or raw gas number.
|
|
36
|
+
* @returns Gas in raw units as a string.
|
|
37
|
+
*/
|
|
38
|
+
export function parseGas(gas) {
|
|
39
|
+
const gasStr = typeof gas === "number" ? gas.toString() : gas;
|
|
40
|
+
const trimmed = gasStr.trim();
|
|
41
|
+
// Parse "X Tgas" format (case insensitive)
|
|
42
|
+
const tgasMatch = trimmed.match(/^([\d.]+)\s+Tgas$/i);
|
|
43
|
+
if (tgasMatch) {
|
|
44
|
+
// Safe to use non-null assertion after match check
|
|
45
|
+
// biome-ignore lint/style/noNonNullAssertion: regex capture group guaranteed to exist when match succeeds
|
|
46
|
+
const tgas = parseFloat(tgasMatch[1]);
|
|
47
|
+
if (Number.isNaN(tgas) || tgas < 0) {
|
|
48
|
+
// biome-ignore lint/style/noNonNullAssertion: same capture group as above
|
|
49
|
+
throw new Error(`Invalid Tgas value: ${tgasMatch[1]}`);
|
|
50
|
+
}
|
|
51
|
+
return BigInt(Math.floor(tgas * 1e12)).toString();
|
|
52
|
+
}
|
|
53
|
+
// Raw number (no unit) - assume it's already in gas units
|
|
54
|
+
// This allows power users to specify exact gas amounts
|
|
55
|
+
if (/^\d+$/.test(trimmed)) {
|
|
56
|
+
return trimmed;
|
|
57
|
+
}
|
|
58
|
+
// Invalid format
|
|
59
|
+
throw new Error(`Invalid gas format: "${gas}"\n` +
|
|
60
|
+
`Expected: "30 Tgas" or Gas.Tgas(30)\n` +
|
|
61
|
+
`Or provide raw gas units as a number string`);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Format gas to TGas.
|
|
65
|
+
*
|
|
66
|
+
* @param gas - Gas in raw units.
|
|
67
|
+
* @param precision - Decimal places (default: 2).
|
|
68
|
+
* @returns Formatted gas with `' Tgas'` suffix.
|
|
69
|
+
*/
|
|
70
|
+
export function formatGas(gas, precision = 2) {
|
|
71
|
+
const amount = typeof gas === "string" ? BigInt(gas) : gas;
|
|
72
|
+
const tgas = Number(amount) / Number(GAS_PER_TGAS);
|
|
73
|
+
return `${tgas.toFixed(precision)} Tgas`;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Convert TGas to raw gas units.
|
|
77
|
+
* @param tgas - Amount in TGas.
|
|
78
|
+
* @returns Gas amount as string.
|
|
79
|
+
*/
|
|
80
|
+
export function toGas(tgas) {
|
|
81
|
+
return (BigInt(Math.floor(tgas * 1e12)) * BigInt(1)).toString();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Convert raw gas to TGas.
|
|
85
|
+
* @param gas - Gas amount in raw units.
|
|
86
|
+
* @returns Amount in TGas.
|
|
87
|
+
*/
|
|
88
|
+
export function toTGas(gas) {
|
|
89
|
+
const amount = typeof gas === "string" ? BigInt(gas) : gas;
|
|
90
|
+
return Number(amount) / Number(GAS_PER_TGAS);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=gas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gas.js","sourceRoot":"","sources":["../../src/utils/gas.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAA;AAoBnD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB;;;OAGG;IACH,IAAI,CAAC,KAAsB;QACzB,OAAO,GAAG,KAAK,OAAO,CAAA;IACxB,CAAC;IAED;;OAEG;IACH,OAAO,EAAE,SAAS;IAClB,GAAG,EAAE,UAAU;CACP,CAAA;AAEV;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,GAAsB;IAC7C,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,GAAG,CAAA;IAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAA;IAE7B,2CAA2C;IAC3C,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;IACrD,IAAI,SAAS,EAAE,CAAC;QACd,mDAAmD;QACnD,0GAA0G;QAC1G,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAE,CAAC,CAAA;QACtC,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACnC,0EAA0E;YAC1E,MAAM,IAAI,KAAK,CAAC,uBAAuB,SAAS,CAAC,CAAC,CAAE,EAAE,CAAC,CAAA;QACzD,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;IACnD,CAAC;IAED,0DAA0D;IAC1D,uDAAuD;IACvD,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,iBAAiB;IACjB,MAAM,IAAI,KAAK,CACb,wBAAwB,GAAG,KAAK;QAC9B,uCAAuC;QACvC,6CAA6C,CAChD,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CAAC,GAAoB,EAAE,SAAS,GAAG,CAAC;IAC3D,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;IAClD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAA;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,IAAY;IAChC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAA;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,MAAM,CAAC,GAAoB;IACzC,MAAM,MAAM,GAAG,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,YAAY,CAAC,CAAA;AAC9C,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for the NEAR client library.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module exposes helpers for working with human-readable amounts and gas,
|
|
6
|
+
* key generation and parsing, NEP-413 message signing, and validation of
|
|
7
|
+
* common NEAR types (account IDs, public/private keys, amounts, gas).
|
|
8
|
+
*/
|
|
9
|
+
export { Amount, type AmountInput, formatAmount, parseAmount, } from "./amount.js";
|
|
10
|
+
export { formatGas, Gas, type GasInput, parseGas } from "./gas.js";
|
|
11
|
+
export * from "./key.js";
|
|
12
|
+
export { generateNep413Nonce, NEP413_TAG, serializeNep413Message, verifyNep413Signature, } from "./nep413.js";
|
|
13
|
+
export { isPrivateKey, isValidAccountId, isValidPublicKey, type PrivateKey, validateAccountId, validatePrivateKey, validatePublicKey, } from "./validation.js";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,MAAM,EACN,KAAK,WAAW,EAChB,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAClE,cAAc,UAAU,CAAA;AACxB,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,UAAU,EACf,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for the NEAR client library.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module exposes helpers for working with human-readable amounts and gas,
|
|
6
|
+
* key generation and parsing, NEP-413 message signing, and validation of
|
|
7
|
+
* common NEAR types (account IDs, public/private keys, amounts, gas).
|
|
8
|
+
*/
|
|
9
|
+
export { Amount, formatAmount, parseAmount, } from "./amount.js";
|
|
10
|
+
export { formatGas, Gas, parseGas } from "./gas.js";
|
|
11
|
+
export * from "./key.js";
|
|
12
|
+
export { generateNep413Nonce, NEP413_TAG, serializeNep413Message, verifyNep413Signature, } from "./nep413.js";
|
|
13
|
+
export { isPrivateKey, isValidAccountId, isValidPublicKey, validateAccountId, validatePrivateKey, validatePublicKey, } from "./validation.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,MAAM,EAEN,YAAY,EACZ,WAAW,GACZ,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,GAAG,EAAiB,QAAQ,EAAE,MAAM,UAAU,CAAA;AAClE,cAAc,UAAU,CAAA;AACxB,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAEhB,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,iBAAiB,CAAA"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { type KeyPair, type PublicKey, type Signature, type SignedMessage, type SignMessageParams } from "../core/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ed25519 key pair implementation.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* Implements the {@link KeyPair} interface used throughout the library and
|
|
7
|
+
* provides NEP-413 message signing via {@link Ed25519KeyPair.signNep413Message}.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Ed25519KeyPair implements KeyPair {
|
|
10
|
+
publicKey: PublicKey;
|
|
11
|
+
secretKey: string;
|
|
12
|
+
private privateKey;
|
|
13
|
+
constructor(secretKey: Uint8Array);
|
|
14
|
+
sign(message: Uint8Array): Signature;
|
|
15
|
+
/**
|
|
16
|
+
* Sign a message according to NEP-413 specification
|
|
17
|
+
*
|
|
18
|
+
* NEP-413 enables off-chain message signing for authentication and ownership verification.
|
|
19
|
+
* The message is signed with a full-access key but does not require gas or blockchain state.
|
|
20
|
+
*
|
|
21
|
+
* @param accountId - The NEAR account ID that owns this key
|
|
22
|
+
* @param params - Message signing parameters (message, recipient, nonce)
|
|
23
|
+
* @returns Signed message with account ID, public key, and base64-encoded signature
|
|
24
|
+
*
|
|
25
|
+
* @see https://github.com/near/NEPs/blob/master/neps/nep-0413.md
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const nonce = crypto.getRandomValues(new Uint8Array(32))
|
|
30
|
+
* const signedMessage = keyPair.signNep413Message("alice.near", {
|
|
31
|
+
* message: "Login to MyApp",
|
|
32
|
+
* recipient: "myapp.near",
|
|
33
|
+
* nonce,
|
|
34
|
+
* })
|
|
35
|
+
* console.log(signedMessage.signature) // Base64-encoded signature
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
signNep413Message(accountId: string, params: SignMessageParams): SignedMessage;
|
|
39
|
+
static fromRandom(): Ed25519KeyPair;
|
|
40
|
+
static fromString(keyString: string): Ed25519KeyPair;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Secp256k1 key pair implementation.
|
|
44
|
+
*
|
|
45
|
+
* NEAR expects secp256k1 public keys to be 64 bytes (uncompressed without 0x04 header).
|
|
46
|
+
* The secp256k1 library returns 65-byte uncompressed keys (with 0x04 header), so we
|
|
47
|
+
* manually remove/add that byte as needed.
|
|
48
|
+
*
|
|
49
|
+
* Signatures are 65 bytes: 64-byte signature + 1-byte recovery ID.
|
|
50
|
+
*/
|
|
51
|
+
export declare class Secp256k1KeyPair implements KeyPair {
|
|
52
|
+
publicKey: PublicKey;
|
|
53
|
+
secretKey: string;
|
|
54
|
+
private privateKey;
|
|
55
|
+
constructor(secretKey: Uint8Array);
|
|
56
|
+
sign(message: Uint8Array): Signature;
|
|
57
|
+
/**
|
|
58
|
+
* Sign a message according to NEP-413 specification
|
|
59
|
+
*
|
|
60
|
+
* NEP-413 enables off-chain message signing for authentication and ownership verification.
|
|
61
|
+
* The message is signed with a full-access key but does not require gas or blockchain state.
|
|
62
|
+
*
|
|
63
|
+
* @param accountId - The NEAR account ID that owns this key
|
|
64
|
+
* @param params - Message signing parameters (message, recipient, nonce)
|
|
65
|
+
* @returns Signed message with account ID, public key, and base64-encoded signature
|
|
66
|
+
*
|
|
67
|
+
* @see https://github.com/near/NEPs/blob/master/neps/nep-0413.md
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const nonce = crypto.getRandomValues(new Uint8Array(32))
|
|
72
|
+
* const signedMessage = keyPair.signNep413Message("alice.near", {
|
|
73
|
+
* message: "Login to MyApp",
|
|
74
|
+
* recipient: "myapp.near",
|
|
75
|
+
* nonce,
|
|
76
|
+
* })
|
|
77
|
+
* console.log(signedMessage.signature) // Base64-encoded signature
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
signNep413Message(accountId: string, params: SignMessageParams): SignedMessage;
|
|
81
|
+
static fromRandom(): Secp256k1KeyPair;
|
|
82
|
+
static fromString(keyString: string): Secp256k1KeyPair;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Generate a new random Ed25519 key pair.
|
|
86
|
+
* @returns A new {@link KeyPair} instance.
|
|
87
|
+
*/
|
|
88
|
+
export declare function generateKey(): KeyPair;
|
|
89
|
+
/**
|
|
90
|
+
* Parse a key string to a {@link KeyPair}.
|
|
91
|
+
*
|
|
92
|
+
* @param keyString - Key string (e.g. `"ed25519:..."` or `"secp256k1:..."`).
|
|
93
|
+
* @returns A concrete {@link Ed25519KeyPair} or {@link Secp256k1KeyPair}.
|
|
94
|
+
*/
|
|
95
|
+
export declare function parseKey(keyString: string): KeyPair;
|
|
96
|
+
/**
|
|
97
|
+
* Parse a public key string to a {@link PublicKey} object.
|
|
98
|
+
*
|
|
99
|
+
* @param publicKeyString - Public key string (e.g. `"ed25519:..."` or `"secp256k1:..."`).
|
|
100
|
+
* @returns {@link PublicKey} instance.
|
|
101
|
+
*/
|
|
102
|
+
export declare function parsePublicKey(publicKeyString: string): PublicKey;
|
|
103
|
+
/**
|
|
104
|
+
* Generate a BIP39 seed phrase (12 words by default)
|
|
105
|
+
* Uses proper BIP39 implementation with cryptographically secure randomness
|
|
106
|
+
* @param wordCount - Number of words (12, 15, 18, 21, or 24). Defaults to 12
|
|
107
|
+
* @returns A BIP39 seed phrase string
|
|
108
|
+
*/
|
|
109
|
+
export declare function generateSeedPhrase(wordCount?: 12 | 15 | 18 | 21 | 24): string;
|
|
110
|
+
/**
|
|
111
|
+
* Parse a BIP39 seed phrase to derive a key pair using proper BIP32/SLIP10 derivation
|
|
112
|
+
* @param phrase - BIP39 seed phrase (12-24 words)
|
|
113
|
+
* @param path - BIP32 derivation path (defaults to "m/44'/397'/0'" for NEAR)
|
|
114
|
+
* @returns KeyPair instance
|
|
115
|
+
*/
|
|
116
|
+
export declare function parseSeedPhrase(phrase: string, path?: string): KeyPair;
|
|
117
|
+
//# sourceMappingURL=key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.d.ts","sourceRoot":"","sources":["../../src/utils/key.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,KAAK,OAAO,EAEZ,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACvB,MAAM,kBAAkB,CAAA;AAIzB;;;;;;GAMG;AACH,qBAAa,cAAe,YAAW,OAAO;IAC5C,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,UAAU,CAAY;gBAElB,SAAS,EAAE,UAAU;IAcjC,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS;IAQpC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,GACxB,aAAa;IAehB,MAAM,CAAC,UAAU,IAAI,cAAc;IAYnC,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc;CAKrD;AAED;;;;;;;;GAQG;AACH,qBAAa,gBAAiB,YAAW,OAAO;IAC9C,SAAS,EAAE,SAAS,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,UAAU,CAAY;gBAElB,SAAS,EAAE,UAAU;IAcjC,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,SAAS;IAapC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,iBAAiB,GACxB,aAAa;IAiBhB,MAAM,CAAC,UAAU,IAAI,gBAAgB;IAmBrC,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;CAKvD;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,CAsBjE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,GAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAO,GACrC,MAAM,CAWR;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAAwB,GAC7B,OAAO,CA4BT"}
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
2
|
+
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
3
|
+
import { base58, base64 } from "@scure/base";
|
|
4
|
+
import { HDKey } from "@scure/bip32";
|
|
5
|
+
import * as bip39 from "@scure/bip39";
|
|
6
|
+
import { wordlist } from "@scure/bip39/wordlists/english.js";
|
|
7
|
+
import { ED25519_KEY_PREFIX, SECP256K1_KEY_PREFIX } from "../core/constants.js";
|
|
8
|
+
import { KeyType, } from "../core/types.js";
|
|
9
|
+
import { InvalidKeyError } from "../errors/index.js";
|
|
10
|
+
import { serializeNep413Message } from "./nep413.js";
|
|
11
|
+
/**
|
|
12
|
+
* Ed25519 key pair implementation.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* Implements the {@link KeyPair} interface used throughout the library and
|
|
16
|
+
* provides NEP-413 message signing via {@link Ed25519KeyPair.signNep413Message}.
|
|
17
|
+
*/
|
|
18
|
+
export class Ed25519KeyPair {
|
|
19
|
+
constructor(secretKey) {
|
|
20
|
+
// secretKey is 64 bytes: [32 bytes private key][32 bytes public key]
|
|
21
|
+
this.privateKey = secretKey.slice(0, 32);
|
|
22
|
+
const publicKeyData = secretKey.slice(32);
|
|
23
|
+
this.publicKey = {
|
|
24
|
+
keyType: KeyType.ED25519,
|
|
25
|
+
data: publicKeyData,
|
|
26
|
+
toString: () => ED25519_KEY_PREFIX + base58.encode(publicKeyData),
|
|
27
|
+
};
|
|
28
|
+
this.secretKey = ED25519_KEY_PREFIX + base58.encode(secretKey);
|
|
29
|
+
}
|
|
30
|
+
sign(message) {
|
|
31
|
+
const signature = ed25519.sign(message, this.privateKey);
|
|
32
|
+
return {
|
|
33
|
+
keyType: KeyType.ED25519,
|
|
34
|
+
data: signature,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sign a message according to NEP-413 specification
|
|
39
|
+
*
|
|
40
|
+
* NEP-413 enables off-chain message signing for authentication and ownership verification.
|
|
41
|
+
* The message is signed with a full-access key but does not require gas or blockchain state.
|
|
42
|
+
*
|
|
43
|
+
* @param accountId - The NEAR account ID that owns this key
|
|
44
|
+
* @param params - Message signing parameters (message, recipient, nonce)
|
|
45
|
+
* @returns Signed message with account ID, public key, and base64-encoded signature
|
|
46
|
+
*
|
|
47
|
+
* @see https://github.com/near/NEPs/blob/master/neps/nep-0413.md
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```typescript
|
|
51
|
+
* const nonce = crypto.getRandomValues(new Uint8Array(32))
|
|
52
|
+
* const signedMessage = keyPair.signNep413Message("alice.near", {
|
|
53
|
+
* message: "Login to MyApp",
|
|
54
|
+
* recipient: "myapp.near",
|
|
55
|
+
* nonce,
|
|
56
|
+
* })
|
|
57
|
+
* console.log(signedMessage.signature) // Base64-encoded signature
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
signNep413Message(accountId, params) {
|
|
61
|
+
// Serialize and hash the message according to NEP-413
|
|
62
|
+
const hash = serializeNep413Message(params);
|
|
63
|
+
// Sign the hash
|
|
64
|
+
const signature = ed25519.sign(hash, this.privateKey);
|
|
65
|
+
// Return signed message with base64-encoded signature
|
|
66
|
+
return {
|
|
67
|
+
accountId,
|
|
68
|
+
publicKey: this.publicKey.toString(),
|
|
69
|
+
signature: base64.encode(signature),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
static fromRandom() {
|
|
73
|
+
const privateKey = ed25519.utils.randomSecretKey();
|
|
74
|
+
const publicKey = ed25519.getPublicKey(privateKey);
|
|
75
|
+
// Combine into 64-byte format for compatibility
|
|
76
|
+
const secretKey = new Uint8Array(64);
|
|
77
|
+
secretKey.set(privateKey, 0);
|
|
78
|
+
secretKey.set(publicKey, 32);
|
|
79
|
+
return new Ed25519KeyPair(secretKey);
|
|
80
|
+
}
|
|
81
|
+
static fromString(keyString) {
|
|
82
|
+
const key = keyString.replace(ED25519_KEY_PREFIX, "");
|
|
83
|
+
const decoded = base58.decode(key);
|
|
84
|
+
return new Ed25519KeyPair(decoded);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Secp256k1 key pair implementation.
|
|
89
|
+
*
|
|
90
|
+
* NEAR expects secp256k1 public keys to be 64 bytes (uncompressed without 0x04 header).
|
|
91
|
+
* The secp256k1 library returns 65-byte uncompressed keys (with 0x04 header), so we
|
|
92
|
+
* manually remove/add that byte as needed.
|
|
93
|
+
*
|
|
94
|
+
* Signatures are 65 bytes: 64-byte signature + 1-byte recovery ID.
|
|
95
|
+
*/
|
|
96
|
+
export class Secp256k1KeyPair {
|
|
97
|
+
constructor(secretKey) {
|
|
98
|
+
// secretKey is 96 bytes: [32 bytes private key][64 bytes public key]
|
|
99
|
+
this.privateKey = secretKey.slice(0, 32);
|
|
100
|
+
const publicKeyData = secretKey.slice(32); // 64 bytes without 0x04 header
|
|
101
|
+
this.publicKey = {
|
|
102
|
+
keyType: KeyType.SECP256K1,
|
|
103
|
+
data: publicKeyData,
|
|
104
|
+
toString: () => SECP256K1_KEY_PREFIX + base58.encode(publicKeyData),
|
|
105
|
+
};
|
|
106
|
+
this.secretKey = SECP256K1_KEY_PREFIX + base58.encode(secretKey);
|
|
107
|
+
}
|
|
108
|
+
sign(message) {
|
|
109
|
+
// Sign with format: 'recovered' to get 65 bytes (recovery ID + signature)
|
|
110
|
+
// This is what NEAR expects: [recovery][r][s]
|
|
111
|
+
const signatureBytes = secp256k1.sign(message, this.privateKey, {
|
|
112
|
+
format: "recovered",
|
|
113
|
+
});
|
|
114
|
+
return {
|
|
115
|
+
keyType: KeyType.SECP256K1,
|
|
116
|
+
data: signatureBytes, // 65 bytes
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Sign a message according to NEP-413 specification
|
|
121
|
+
*
|
|
122
|
+
* NEP-413 enables off-chain message signing for authentication and ownership verification.
|
|
123
|
+
* The message is signed with a full-access key but does not require gas or blockchain state.
|
|
124
|
+
*
|
|
125
|
+
* @param accountId - The NEAR account ID that owns this key
|
|
126
|
+
* @param params - Message signing parameters (message, recipient, nonce)
|
|
127
|
+
* @returns Signed message with account ID, public key, and base64-encoded signature
|
|
128
|
+
*
|
|
129
|
+
* @see https://github.com/near/NEPs/blob/master/neps/nep-0413.md
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const nonce = crypto.getRandomValues(new Uint8Array(32))
|
|
134
|
+
* const signedMessage = keyPair.signNep413Message("alice.near", {
|
|
135
|
+
* message: "Login to MyApp",
|
|
136
|
+
* recipient: "myapp.near",
|
|
137
|
+
* nonce,
|
|
138
|
+
* })
|
|
139
|
+
* console.log(signedMessage.signature) // Base64-encoded signature
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
signNep413Message(accountId, params) {
|
|
143
|
+
// Serialize and hash the message according to NEP-413
|
|
144
|
+
const hash = serializeNep413Message(params);
|
|
145
|
+
// Sign the hash with format: 'recovered' for secp256k1
|
|
146
|
+
const signature = secp256k1.sign(hash, this.privateKey, {
|
|
147
|
+
format: "recovered",
|
|
148
|
+
});
|
|
149
|
+
// Return signed message with base64-encoded signature
|
|
150
|
+
return {
|
|
151
|
+
accountId,
|
|
152
|
+
publicKey: this.publicKey.toString(),
|
|
153
|
+
signature: base64.encode(signature),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
static fromRandom() {
|
|
157
|
+
// Generate random 32-byte private key
|
|
158
|
+
const privateKey = new Uint8Array(32);
|
|
159
|
+
crypto.getRandomValues(privateKey);
|
|
160
|
+
// Get uncompressed public key (65 bytes with 0x04 header)
|
|
161
|
+
const publicKeyFull = secp256k1.getPublicKey(privateKey, false);
|
|
162
|
+
// Remove 0x04 header to get 64 bytes for NEAR
|
|
163
|
+
const publicKey = publicKeyFull.slice(1);
|
|
164
|
+
// Combine into 96-byte format: 32 bytes private + 64 bytes public
|
|
165
|
+
const secretKey = new Uint8Array(96);
|
|
166
|
+
secretKey.set(privateKey, 0);
|
|
167
|
+
secretKey.set(publicKey, 32);
|
|
168
|
+
return new Secp256k1KeyPair(secretKey);
|
|
169
|
+
}
|
|
170
|
+
static fromString(keyString) {
|
|
171
|
+
const key = keyString.replace(SECP256K1_KEY_PREFIX, "");
|
|
172
|
+
const decoded = base58.decode(key);
|
|
173
|
+
return new Secp256k1KeyPair(decoded);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Generate a new random Ed25519 key pair.
|
|
178
|
+
* @returns A new {@link KeyPair} instance.
|
|
179
|
+
*/
|
|
180
|
+
export function generateKey() {
|
|
181
|
+
return Ed25519KeyPair.fromRandom();
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Parse a key string to a {@link KeyPair}.
|
|
185
|
+
*
|
|
186
|
+
* @param keyString - Key string (e.g. `"ed25519:..."` or `"secp256k1:..."`).
|
|
187
|
+
* @returns A concrete {@link Ed25519KeyPair} or {@link Secp256k1KeyPair}.
|
|
188
|
+
*/
|
|
189
|
+
export function parseKey(keyString) {
|
|
190
|
+
if (keyString.startsWith(ED25519_KEY_PREFIX)) {
|
|
191
|
+
return Ed25519KeyPair.fromString(keyString);
|
|
192
|
+
}
|
|
193
|
+
if (keyString.startsWith(SECP256K1_KEY_PREFIX)) {
|
|
194
|
+
return Secp256k1KeyPair.fromString(keyString);
|
|
195
|
+
}
|
|
196
|
+
throw new InvalidKeyError(`Unsupported key type: ${keyString}`);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Parse a public key string to a {@link PublicKey} object.
|
|
200
|
+
*
|
|
201
|
+
* @param publicKeyString - Public key string (e.g. `"ed25519:..."` or `"secp256k1:..."`).
|
|
202
|
+
* @returns {@link PublicKey} instance.
|
|
203
|
+
*/
|
|
204
|
+
export function parsePublicKey(publicKeyString) {
|
|
205
|
+
if (publicKeyString.startsWith(ED25519_KEY_PREFIX)) {
|
|
206
|
+
const key = publicKeyString.replace(ED25519_KEY_PREFIX, "");
|
|
207
|
+
const decoded = base58.decode(key);
|
|
208
|
+
return {
|
|
209
|
+
keyType: KeyType.ED25519,
|
|
210
|
+
data: decoded,
|
|
211
|
+
toString: () => publicKeyString,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
if (publicKeyString.startsWith(SECP256K1_KEY_PREFIX)) {
|
|
215
|
+
const key = publicKeyString.replace(SECP256K1_KEY_PREFIX, "");
|
|
216
|
+
const decoded = base58.decode(key);
|
|
217
|
+
return {
|
|
218
|
+
keyType: KeyType.SECP256K1,
|
|
219
|
+
data: decoded,
|
|
220
|
+
toString: () => publicKeyString,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
throw new InvalidKeyError(`Unsupported public key type: ${publicKeyString}`);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Generate a BIP39 seed phrase (12 words by default)
|
|
227
|
+
* Uses proper BIP39 implementation with cryptographically secure randomness
|
|
228
|
+
* @param wordCount - Number of words (12, 15, 18, 21, or 24). Defaults to 12
|
|
229
|
+
* @returns A BIP39 seed phrase string
|
|
230
|
+
*/
|
|
231
|
+
export function generateSeedPhrase(wordCount = 12) {
|
|
232
|
+
// Map word count to entropy bits (as per BIP39 spec)
|
|
233
|
+
const entropyBits = wordCount * 11 - wordCount / 3;
|
|
234
|
+
const entropyBytes = entropyBits / 8;
|
|
235
|
+
// Generate cryptographically secure random entropy
|
|
236
|
+
const entropy = new Uint8Array(entropyBytes);
|
|
237
|
+
crypto.getRandomValues(entropy);
|
|
238
|
+
// Generate mnemonic from entropy
|
|
239
|
+
return bip39.entropyToMnemonic(entropy, wordlist);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Parse a BIP39 seed phrase to derive a key pair using proper BIP32/SLIP10 derivation
|
|
243
|
+
* @param phrase - BIP39 seed phrase (12-24 words)
|
|
244
|
+
* @param path - BIP32 derivation path (defaults to "m/44'/397'/0'" for NEAR)
|
|
245
|
+
* @returns KeyPair instance
|
|
246
|
+
*/
|
|
247
|
+
export function parseSeedPhrase(phrase, path = "m/44'/397'/0'") {
|
|
248
|
+
// Validate the mnemonic
|
|
249
|
+
if (!bip39.validateMnemonic(phrase, wordlist)) {
|
|
250
|
+
throw new InvalidKeyError("Invalid BIP39 seed phrase");
|
|
251
|
+
}
|
|
252
|
+
// Convert mnemonic to seed (64 bytes)
|
|
253
|
+
const seed = bip39.mnemonicToSeedSync(phrase);
|
|
254
|
+
// Derive HD key using BIP32 with ed25519 (SLIP10)
|
|
255
|
+
// Note: HDKey from @scure/bip32 supports ed25519 via SLIP10
|
|
256
|
+
const hdkey = HDKey.fromMasterSeed(seed);
|
|
257
|
+
const derived = hdkey.derive(path);
|
|
258
|
+
if (!derived.privateKey) {
|
|
259
|
+
throw new InvalidKeyError("Failed to derive private key from seed phrase");
|
|
260
|
+
}
|
|
261
|
+
// Get the ed25519 public key from private key
|
|
262
|
+
const privateKey = derived.privateKey;
|
|
263
|
+
const publicKey = ed25519.getPublicKey(privateKey);
|
|
264
|
+
// Combine into 64-byte format for compatibility
|
|
265
|
+
const secretKey = new Uint8Array(64);
|
|
266
|
+
secretKey.set(privateKey, 0);
|
|
267
|
+
secretKey.set(publicKey, 32);
|
|
268
|
+
return new Ed25519KeyPair(secretKey);
|
|
269
|
+
}
|
|
270
|
+
//# sourceMappingURL=key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key.js","sourceRoot":"","sources":["../../src/utils/key.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NEP-413: Message signing utilities
|
|
3
|
+
*
|
|
4
|
+
* NEP-413 enables off-chain message signing for authentication and ownership verification
|
|
5
|
+
* without gas fees or blockchain transactions.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/near/NEPs/blob/master/neps/nep-0413.md
|
|
8
|
+
*/
|
|
9
|
+
import type { SignedMessage, SignMessageParams } from "../core/types.js";
|
|
10
|
+
/**
|
|
11
|
+
* NEP-413 tag prefix: 2^31 + 413 = 2147484061
|
|
12
|
+
*
|
|
13
|
+
* This prefix ensures that signed messages cannot be confused with valid transactions.
|
|
14
|
+
* The tag makes the message too long to be a valid signer account ID.
|
|
15
|
+
*/
|
|
16
|
+
export declare const NEP413_TAG = 2147484061;
|
|
17
|
+
/**
|
|
18
|
+
* NEP-413 message payload schema
|
|
19
|
+
*
|
|
20
|
+
* Fields are serialized in this order:
|
|
21
|
+
* 1. message: string - The message to sign
|
|
22
|
+
* 2. nonce: [u8; 32] - 32-byte nonce for replay protection
|
|
23
|
+
* 3. recipient: string - Recipient identifier (e.g., "alice.near" or "myapp.com")
|
|
24
|
+
* 4. callbackUrl: Option<string> - Optional callback URL for web wallets
|
|
25
|
+
*/
|
|
26
|
+
export declare const Nep413PayloadSchema: import("@zorsh/zorsh").Schema<{
|
|
27
|
+
message: string;
|
|
28
|
+
nonce: number[];
|
|
29
|
+
recipient: string;
|
|
30
|
+
callbackUrl: string | null;
|
|
31
|
+
}, string>;
|
|
32
|
+
/**
|
|
33
|
+
* Serialize NEP-413 message parameters for signing
|
|
34
|
+
*
|
|
35
|
+
* Serialization steps:
|
|
36
|
+
* 1. Serialize the tag (2147484061) as u32
|
|
37
|
+
* 2. Serialize the payload (message, nonce, recipient, callbackUrl)
|
|
38
|
+
* 3. Concatenate: tag_bytes + payload_bytes
|
|
39
|
+
* 4. Hash with SHA256
|
|
40
|
+
*
|
|
41
|
+
* @param params - Message signing parameters
|
|
42
|
+
* @returns Serialized and hashed message ready for signing
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```typescript
|
|
46
|
+
* const nonce = crypto.getRandomValues(new Uint8Array(32))
|
|
47
|
+
* const hash = serializeNep413Message({
|
|
48
|
+
* message: "Login to MyApp",
|
|
49
|
+
* recipient: "myapp.near",
|
|
50
|
+
* nonce,
|
|
51
|
+
* })
|
|
52
|
+
* const signature = keyPair.sign(hash)
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare function serializeNep413Message(params: SignMessageParams): Uint8Array;
|
|
56
|
+
/**
|
|
57
|
+
* Verify a NEP-413 signed message
|
|
58
|
+
*
|
|
59
|
+
* Verification steps:
|
|
60
|
+
* 1. Reconstruct the payload from parameters
|
|
61
|
+
* 2. Serialize and hash (tag + payload)
|
|
62
|
+
* 3. Verify the signature against the hash using the public key
|
|
63
|
+
*
|
|
64
|
+
* @param signedMessage - The signed message to verify
|
|
65
|
+
* @param params - Original message parameters (must match what was signed)
|
|
66
|
+
* @returns true if signature is valid, false otherwise
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const isValid = verifyNep413Signature(signedMessage, {
|
|
71
|
+
* message: "Login to MyApp",
|
|
72
|
+
* recipient: "myapp.near",
|
|
73
|
+
* nonce,
|
|
74
|
+
* })
|
|
75
|
+
* if (isValid) {
|
|
76
|
+
* console.log("Signature verified!")
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function verifyNep413Signature(signedMessage: SignedMessage, params: SignMessageParams): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Generate a random nonce for NEP-413 message signing
|
|
83
|
+
*
|
|
84
|
+
* @returns 32-byte random nonce
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* ```typescript
|
|
88
|
+
* const nonce = generateNep413Nonce()
|
|
89
|
+
* const signedMessage = await near.signMessage({
|
|
90
|
+
* message: "Login to MyApp",
|
|
91
|
+
* recipient: "myapp.near",
|
|
92
|
+
* nonce,
|
|
93
|
+
* })
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function generateNep413Nonce(): Uint8Array;
|
|
97
|
+
//# sourceMappingURL=nep413.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nep413.d.ts","sourceRoot":"","sources":["../../src/utils/nep413.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGxE;;;;;GAKG;AACH,eAAO,MAAM,UAAU,aAAa,CAAA;AAEpC;;;;;;;;GAQG;AACH,eAAO,MAAM,mBAAmB;;;;;UAK9B,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,GAAG,UAAU,CAuB5E;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,aAAa,EAC5B,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAiCT;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,mBAAmB,IAAI,UAAU,CAEhD"}
|