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

feat: client #1372

wants to merge 36 commits into from

Conversation

andy-haynes
Copy link
Collaborator

@andy-haynes andy-haynes commented Aug 19, 2024

Pre-flight checklist

  • I have read the Contributing Guidelines on pull requests.
  • Commit messages follow the conventional commits spec
  • If this is a code change: I have written unit tests.
  • If this changes code in a published package: I have run pnpm changeset to create a changeset JSON document appropriate for this change.
  • If this is a new API or substantial change: the PR has an accompanying issue (closes #0000) and the maintainers have approved on my working plan.

Motivation

WIP implementation for new NAJ client library. Example proposed usage compared to current usage:

Current implementation

import { Account, Connection, providers } from 'near-api-js';

(async function () {
  const account = new Account(Connection.fromConfig({
    networkId: 'testnet',
    provider: new providers.JsonRpcProvider({ url: 'https://rpc.testnet.near.org' }),
    signer: {}, // signer not needed here but an object must be passed
  }), 'dontcare'); // required but not used; most string values should work here

  const app = await account.viewFunction({
    contractId: 'v1.chain-hosted-ui.testnet',
    methodName: 'get_application',
    args: { application: 'react-vite-example', account_id: 'tuster.testnet' },
  });

  console.log(app);
}());

Potential implementations

import { getRpcProvider, view } from '@near-js/client';

(async function () {
  const app = await view({
    contract: 'v1.chain-hosted-ui.testnet',
    method: 'get_application',
    args: {
    application: 'react-vite-example', account_id: 'tuster.testnet' },
    deps: { rpcProvider: getRpcProvider('testnet') }
  });

  console.log(app);
}());

Call function

Call functions add a signing component, which requires initialization of an underlying key store. It still relies on the Account class, with the represented account being the transaction signer. The method currently takes several parameters that are only applicable in very specific use cases, making it awkward for general use.

The proposed implementation exposes a dedicated method with simple arguments. Initialization of the signer is much more clear by way of a simple initialization method which can trivially be extended to accommodate other signers.

Current implementation

import {
  Account,
  Connection,
  InMemorySigner,
  keyStores,
  KeyPair,
  providers,
} from 'near-api-js';
import { SIGNER, SIGNER_KEY } from './constants';

(async function () {
  const keyStore = new keyStores.InMemoryKeyStore();
  await keyStore.setKey(
    'testnet',
    SIGNER,
    KeyPair.fromString(SIGNER_KEY)
  );

  const account = new Account(Connection.fromConfig({
    networkId: 'testnet',
    provider: new providers.JsonRpcProvider({ url: 'https://rpc.testnet.near.org' }),
    signer: new InMemorySigner(keyStore),
  }), SIGNER);

  const outcome = await account.functionCall({
    contractId: 'v1.chain-hosted-ui.testnet',
    methodName: 'get_application',
    args: { application: 'react-vite-example', account_id: 'tuster.testnet' },
    gas: 300000000000000n,
  });

  console.log(providers.getTransactionLastResult(outcome));
}());

Potential implementations

import { call, getRpcProvider, getSignerFromPrivateKey } from '@near-js/client';
import { SIGNER, SIGNER_KEY } from './constants';

(async function() {
  const signer = await getSignerFromPrivateKey(SIGNER, 'testnet', SIGNER_KEY);
  const rpcProvider = getRpcProvider('testnet');

  const result = await call({
    contract: 'v1.chain-hosted-ui.testnet',
    method: 'get_application',
    args: { application: 'react-vite-example', account_id: 'tuster.testnet' },
    deps: { sender: SIGNER, signer, rpcProvider },
  });

  console.log(result);
}());

Create account

Current implementation

import {
  Account,
  Connection,
  InMemorySigner,
  KeyPair,
  keyStores,
  providers,
  utils,
} from 'near-api-js';
import { SIGNER, SIGNER_KEY } from './constants';

(async function () {
  const keyStore = new keyStores.InMemoryKeyStore();
  await keyStore.setKey(
    'testnet',
    SIGNER,
    KeyPair.fromString(SIGNER_KEY)
  );

  const keyPair = utils.KeyPairEd25519.fromRandom();
  const publicKey = keyPair.publicKey.toString();

  const config = Connection.fromConfig({
    networkId: 'testnet',
    provider: new providers.JsonRpcProvider({ url: 'https://rpc.testnet.near.org' }),
    signer: new InMemorySigner(keyStore),
  });
  const creatorAccount = new Account(config, SIGNER);

  const newAccountId = `new-account-${Date.now().valueOf()}.testnet`;
  await creatorAccount.functionCall({
    contractId: 'testnet',
    methodName: 'create_account',
    args: {
      new_account_id: newAccountId,
      new_public_key: publicKey,
    },
    gas: 300000000000000n,
    attachedDeposit: 100n,
  });

  console.log(await (new Account(config, newAccountId).state()));
}());

Potential implementations

import { KeyPairEd25519 } from '@near-js/crypto';

import { createAccount, getRpcProvider, getSignerFromPrivateKey, viewAccount } from '@near-js/client';
import { SIGNER, SIGNER_KEY } from './constants';

(async function () {
  const rpcProvider = getRpcProvider('testnet');
  const signer = await getSignerFromPrivateKey(SIGNER, 'testnet', SIGNER_KEY);

  const keyPair = KeyPairEd25519.fromRandom();
  const publicKey = keyPair.publicKey;

  const newAccountId = `new-account-${Date.now().valueOf()}.testnet`;
  
  const result = await createAccount({ newAccountId, publicKey, creatingAccountId: 'testnet', deps: {
    rpcProvider,
    signer,
    sender: SIGNER,
    attachedDeposit: 100n,
  }});

  console.log(await viewAccount(newAccountId, { rpcProvider }));
}());

Test Plan

Related issues/PRs

Copy link

changeset-bot bot commented Aug 19, 2024

⚠️ No Changeset found

Latest commit: 3dc94de

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@andy-haynes andy-haynes changed the base branch from master to feat/bundling-enhancements August 19, 2024 16:48
@andy-haynes andy-haynes force-pushed the feat/bundling-enhancements branch 3 times, most recently from ecdaf67 to e5e4203 Compare August 19, 2024 23:15
@andy-haynes andy-haynes force-pushed the feat/bundling-enhancements branch 2 times, most recently from 015c916 to e1e7c2f Compare August 20, 2024 21:25
@andy-haynes andy-haynes force-pushed the feat/bundling-enhancements branch 2 times, most recently from 096c8d4 to 2fdb57d Compare August 28, 2024 00:17
Base automatically changed from feat/bundling-enhancements to master September 4, 2024 00:11
@andy-haynes andy-haynes force-pushed the feat/client branch 2 times, most recently from 60721a0 to 7234a4d Compare September 12, 2024 04:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: NEW❗
Development

Successfully merging this pull request may close these issues.

1 participant