Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: client #1372

Draft
wants to merge 36 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9ff900c
feat: client lib init
andy-haynes Aug 9, 2024
f83ea5d
refactor: organize
andy-haynes Aug 9, 2024
22fcef7
test: test/lint commands
andy-haynes Aug 28, 2024
9c74649
feat: add curve type, reorganize types
andy-haynes Aug 29, 2024
d6b6955
fix: contract methods
andy-haynes Aug 29, 2024
6a91707
docs: jsdocs
andy-haynes Aug 29, 2024
524d6dd
feat: delete access key method
andy-haynes Aug 29, 2024
26d7a17
feat: remove nonce as parameter
andy-haynes Aug 29, 2024
0934ae7
feat: parse public key strings
andy-haynes Sep 3, 2024
62e3485
feat: deployContract and deleteAccount methods
andy-haynes Sep 3, 2024
c0fcd34
chore: fix linting
andy-haynes Sep 4, 2024
4305783
feat: staking
andy-haynes Sep 5, 2024
3b9e521
feat: return entire response from single action calls
andy-haynes Sep 5, 2024
7b8a290
feat: public key utils
andy-haynes Sep 5, 2024
3646aa3
feat: create account
andy-haynes Sep 6, 2024
0edf382
feat: funded testnet account creator
andy-haynes Sep 6, 2024
36e8b5d
fix: fetch dependency
andy-haynes Sep 11, 2024
6402f7d
feat: group signing/keystore modules under dedicated path
andy-haynes Sep 11, 2024
88f5c92
refactor: consolidate imports
andy-haynes Sep 11, 2024
dde6f86
feat: fixes, interface updates
andy-haynes Sep 12, 2024
27271b7
feat: update cookbook examples
andy-haynes Sep 12, 2024
97bae8e
chore: fix cookbook lint scripts
andy-haynes Sep 12, 2024
4c310a0
fix: simplify scripts
andy-haynes Sep 12, 2024
843de04
feat: more cookbook examples, docs
andy-haynes Sep 12, 2024
53c2d27
feat: provider options and missing types
andy-haynes Sep 14, 2024
c230e9b
feat: cookbook updates
andy-haynes Sep 14, 2024
d326e50
feat: add SignedTransactionComposer
andy-haynes Sep 17, 2024
503de05
feat: meta transaction support
andy-haynes Sep 17, 2024
0d87a82
chore: useless wrapper
andy-haynes Sep 17, 2024
9ee9835
feat: more cookbook updates
andy-haynes Sep 17, 2024
295df17
feat: ledger
andy-haynes Sep 18, 2024
951b46a
feat: toSignedTransaction method
andy-haynes Sep 18, 2024
2fa73c1
chore: update cookbook dependencies
andy-haynes Sep 18, 2024
32d17ae
feat: optional public key cache for ledger
andy-haynes Sep 19, 2024
85cb910
feat: transaction validation
andy-haynes Sep 19, 2024
3dc94de
feat: composer refactor, better meta transaction support
andy-haynes Sep 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions packages/client/.eslintrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
env:
es6: true
node: true
extends:
- 'eslint:recommended'
- 'plugin:@typescript-eslint/eslint-recommended'
- 'plugin:@typescript-eslint/recommended'
parser: '@typescript-eslint/parser'
rules:
no-inner-declarations: off
indent:
- error
- 2
- SwitchCase: 1
'@typescript-eslint/no-explicit-any': off

parserOptions:
ecmaVersion: 2018
sourceType: module
8 changes: 8 additions & 0 deletions packages/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# @near-js/client

TODO

# License

This repository is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See [LICENSE](https://github.com/near/near-api-js/blob/master/LICENSE) and [LICENSE-APACHE](https://github.com/near/near-api-js/blob/master/LICENSE-APACHE) for details.
13 changes: 13 additions & 0 deletions packages/client/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default {
preset: 'ts-jest',
collectCoverage: true,
testEnvironment: 'node',
testRegex: "(/tests/.*|(\\.|/)(test|spec))\\.[jt]sx?$",
transform: {
'^.+\\.[tj]s$': ['ts-jest', {
tsconfig: {
allowJs: true,
},
}],
},
};
49 changes: 49 additions & 0 deletions packages/client/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@near-js/client",
"version": "0.0.1",
"description": "",
"main": "lib/esm/index.js",
"type": "module",
"scripts": {
"build": "pnpm compile:esm && pnpm compile:cjs",
"compile:esm": "tsc -p tsconfig.json",
"compile:cjs": "tsc -p tsconfig.cjs.json && cjsify ./lib/commonjs",
"lint": "eslint -c .eslintrc.yml src/**/*.ts --no-eslintrc --no-error-on-unmatched-pattern",
"lint:fix": "eslint -c .eslintrc.yml src/**/*.ts --no-eslintrc --no-error-on-unmatched-pattern --fix"
},
"dependencies": {
"@ledgerhq/hw-transport-node-hid": "6.29.4",
"@near-js/crypto": "workspace:*",
"@near-js/keystores": "workspace:*",
"@near-js/keystores-node": "workspace:*",
"@near-js/providers": "workspace:*",
"@near-js/signers": "workspace:*",
"@near-js/transactions": "workspace:*",
"@near-js/types": "workspace:*",
"@near-js/utils": "workspace:*",
"@noble/hashes": "1.3.3",
"isomorphic-fetch": "3.0.0",
"near-ledger-js": "0.2.1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@ledgerhq/devices": "8.4.3",
"@ledgerhq/hw-transport-node-hid-noevents": "6.30.4",
"@ledgerhq/logs": "6.12.0",
"@types/ledgerhq__hw-transport": "4.21.8",
"@types/node": "20.0.0",
"@types/node-hid": "1.3.4",
"build": "workspace:*",
"tsconfig": "workspace:*",
"typescript": "5.4.5"
},
"files": [
"lib"
],
"exports": {
"require": "./lib/commonjs/index.cjs",
"import": "./lib/esm/index.js"
}
}
29 changes: 29 additions & 0 deletions packages/client/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const ACCOUNT_CREATION_DEPOSIT = BigInt(100);
export const MAINNET_RPC_URL = 'https://rpc.mainnet.near.org';
export const TESTNET_RPC_URL = 'https://rpc.testnet.near.org';
export const DEFAULT_FILESYSTEM_KEYSTORE_PATH = '.near-credentials';
export const DEFAULT_META_TRANSACTION_BLOCK_HEIGHT_TTL = BigInt(100);

export const LEDGER_HD_PATH = `44'/397'/0'/0'/1`;

export const MAX_GAS = 300000000000000n;

export const PAGODA_RPC_ENDPOINTS_MAINNET = [
'https://rpc.near.org',
'https://rpc.mainnet.pagoda.co',
];

export const PAGODA_RPC_ARCHIVAL_ENDPOINTS_MAINNET = [
'https://archival-rpc.near.org',
];

export const PAGODA_RPC_ENDPOINTS_TESTNET = [
'https://rpc.testnet.near.org',
'https://rpc.testnet.pagoda.co',
];

export const PAGODA_RPC_ARCHIVAL_ENDPOINTS_TESTNET = [
'https://archival-rpc.testnet.near.org',
];

export const KITWALLET_FUNDED_TESTNET_ACCOUNT_ENDPOINT = 'https://testnet-api.kitwallet.app/account';
17 changes: 17 additions & 0 deletions packages/client/src/crypto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { CurveType, KeyPair, KeyPairString } from '@near-js/crypto';

/**
* Generate a random key pair for the specified elliptic curve
* @param curve elliptic curve (e.g. `ed25519`)
*/
export function generateRandomKeyPair(curve: CurveType) {
return KeyPair.fromRandom(curve);
}

/**
* Parse a signing key pair from a private key string
* @param privateKey private key string
*/
export function parseKeyPair(privateKey: KeyPairString) {
return KeyPair.fromString(privateKey);
}
38 changes: 38 additions & 0 deletions packages/client/src/funded_account.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { FinalExecutionOutcome } from '@near-js/types';
import fetch from 'isomorphic-fetch';

import { KITWALLET_FUNDED_TESTNET_ACCOUNT_ENDPOINT } from './constants';
import { NewAccountParams } from './interfaces';

interface CreateFundedTestnetAccountParams extends NewAccountParams {
endpointUrl?: string;
}

/**
* Create a new funded testnet account via faucet REST endpoint
* (e.g. create `new.testnet` with a preset amount of Near)
* @param endpointUrl REST endpoint for the funded testnet account creation (defaults to the current Near Contract Helper endpoint)
* @param newAccount name of the created account
* @param newPublicKey public key for the created account's initial full access key
*/
export async function createFundedTestnetAccount({
newAccount,
newPublicKey,
endpointUrl = KITWALLET_FUNDED_TESTNET_ACCOUNT_ENDPOINT,
}: CreateFundedTestnetAccountParams) {
const res = await fetch(endpointUrl, {
method: 'POST',
body: JSON.stringify({
newAccountId: newAccount,
newAccountPublicKey: newPublicKey,
}),
headers: { 'Content-Type': 'application/json' },
});

const { ok, status } = res;
if (!ok) {
throw new Error(`Failed to create account on ${endpointUrl}: ${status}`);
}

return await res.json() as FinalExecutionOutcome;
}
10 changes: 10 additions & 0 deletions packages/client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export { formatNearAmount } from '@near-js/utils';

export * from './constants';
export * from './crypto';
export * from './funded_account';
export * from './interfaces';
export * from './providers';
export * from './signing';
export * from './transactions';
export * from './view';
20 changes: 20 additions & 0 deletions packages/client/src/interfaces/dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { PublicKey } from '@near-js/crypto';

import type { RpcQueryProvider } from './providers';

export interface Dependent<T> {
deps: T;
}

export interface MessageSigner {
getPublicKey(): Promise<PublicKey>;
signMessage(m: Uint8Array): Promise<Uint8Array>;
}

export interface RpcProviderDependency {
rpcProvider: RpcQueryProvider;
}

export interface SignerDependency {
signer: MessageSigner;
}
4 changes: 4 additions & 0 deletions packages/client/src/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './dependencies';
export * from './providers';
export * from './transactions';
export * from './view';
25 changes: 25 additions & 0 deletions packages/client/src/interfaces/providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type {
BlockReference,
BlockResult,
ChunkId,
ChunkResult,
FinalExecutionOutcome,
QueryResponseKind,
TxExecutionStatus,
} from '@near-js/types';
import type { SignedTransaction } from '@near-js/transactions';

interface GetTransactionParams {
transactionHash: string;
account: string;
includeReceipts?: boolean;
waitUntil?: TxExecutionStatus;
}

export interface RpcQueryProvider {
block(block: BlockReference): Promise<BlockResult>;
chunk(chunkId: ChunkId): Promise<ChunkResult>;
getTransaction(params: GetTransactionParams): Promise<FinalExecutionOutcome>;
sendTransaction(transaction: SignedTransaction): Promise<FinalExecutionOutcome>;
query<T extends QueryResponseKind>(...args: any[]): Promise<T>;
}
99 changes: 99 additions & 0 deletions packages/client/src/interfaces/transactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import type { Transaction } from '@near-js/transactions';

import type { TransactionComposer } from '../transactions';
import type { Dependent, RpcProviderDependency, SignerDependency } from './dependencies';
import type { RpcProviderQueryParams } from './view';
import { BlockHash } from '@near-js/types';
import { PublicKey } from '@near-js/crypto';

export interface SignAndSendTransactionDependency extends Dependent<RpcProviderDependency & SignerDependency> {}

export interface SignAndSendParams extends SignAndSendTransactionDependency, RpcProviderQueryParams {}

export interface ExternalActionTransaction extends SignAndSendParams {
receiver: string;
sender: string;
}

export interface ReflexiveActionTransaction extends SignAndSendParams {
account: string;
}

export interface SignAndSendComposerParams extends SignAndSendParams, RpcProviderQueryParams {
composer: TransactionComposer;
}

export interface SignAndSendTransactionParams extends SignAndSendTransactionDependency {
transaction: Transaction;
}

export interface FunctionCallParams<T = object> extends ExternalActionTransaction {
method: string;
args?: T;
deposit?: bigint;
gas?: bigint;
}

export interface TransferParams extends ExternalActionTransaction {
amount: bigint;
}

export interface StakeParams extends ReflexiveActionTransaction {
amount: bigint;
publicKey: string;
}

export interface DeleteAccountParams extends ReflexiveActionTransaction {
beneficiaryId: string;
}

export interface DeployContractParams extends ReflexiveActionTransaction {
code: Uint8Array
}

interface AddAccessKeyParams extends ReflexiveActionTransaction {
publicKey: string;
}

export interface ModifyAccessKeyParams extends AddAccessKeyParams {}

export interface AddFunctionCallAccessKeyParams extends AddAccessKeyParams {
contract: string;
methodNames: string[];
allowance?: bigint;
}

export interface SignTransactionParams extends Dependent<SignerDependency> {
transaction: Transaction;
}

export interface NewAccountParams {
newAccount: string;
newPublicKey: string;
}

export interface CreateAccountParams extends SignAndSendParams, NewAccountParams {
account: string;
initialBalance: bigint;
}

export interface CreateTopLevelAccountParams extends CreateAccountParams {
contract: string
}

export interface TransactionOptions {
blockHash?: BlockHash;
nonce?: bigint;
publicKey?: PublicKey;
receiver?: string;
sender?: string;
}

export interface MetaTransactionOptions extends TransactionOptions {
blockHeightTtl?: bigint;
maxBlockHeight?: bigint;
}

export interface SignedTransactionOptions extends TransactionOptions, SignAndSendTransactionDependency {
}

27 changes: 27 additions & 0 deletions packages/client/src/interfaces/view.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { BlockReference } from '@near-js/types';

import { Dependent, RpcProviderDependency } from './dependencies';

export interface RpcProviderQueryParams {
blockReference?: BlockReference;
}

export interface ViewBaseParams extends Dependent<RpcProviderDependency>, RpcProviderQueryParams {
}

export interface ViewAccountParams extends ViewBaseParams {
account: string;
}

export interface ViewParams<T = object> extends ViewAccountParams {
method: string;
args?: T;
}

export interface ViewContractStateParams extends ViewAccountParams {
prefix: string | Uint8Array;
}

export interface ViewAccessKeyParams extends ViewAccountParams {
publicKey: string;
}
Loading
Loading