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

refactor client config to use chainId string #10

Merged
merged 9 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
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
58 changes: 34 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,23 @@ Welcome to the documents for Story Protocol SDK. The SDK provides the APIs for d
## How to use Story Protocol SDK in Your Project

### Install Story Protocol core SDK

Suppose you already have a node project or created a new node project. First, you need to install `@story-protocol/core-sdk` in your project. You can use one of the following command to install the package:

Use `npm`:

```
npm install --save @story-protocol/core-sdk viem
```

Use `pnpm`:

```
pnpm install @story-protocol/core-sdk viem
```

Use `yarn`:

```
yarn add @story-protocol/core-sdk viem
```
Expand Down Expand Up @@ -57,39 +61,38 @@ Next, we need create a client to access Story Protocol by using private key or f
Here is the way to create a Story Protocol client with the private key:

```typescript
import { privateKeyToAccount } from "viem/accounts";
import { privateKeyToAccount } from 'viem/accounts';

const PRIVATE_KEY = process.env.PRIVATE_KEY || "0x";
const PRIVATE_KEY = process.env.PRIVATE_KEY || '0x';
const account = privateKeyToAccount(PRIVATE_KEY as `0x${string}`);

// Instantiate the Story Client for readonly operations, using default
// Instantiate the Story Client for readonly operations, using default
export const realonlyClient = StoryClient.newReadOnlyClient({});

// Instantiate the Story Client, test environment required for alpha release.
// The private key is also required for written operations.
export const client = StoryClient.newClient({account});
export const client = StoryClient.newClient({ account });
```

Here is the way to create a Story Protocol with wallet app:

```typescript
import { createWalletClient, custom } from 'viem'
import { sepolia } from 'viem/chains'
import { createWalletClient, custom } from 'viem';

const walletClient = createWalletClient({
chain: sepolia,
transport: custom(window.ethereum)
})
chainId: 'sepolia',
transport: custom(window.ethereum),
});

// Retrieve the first account for eth_requestAccounts method
const account = await walletClient.requestAddresses()[0]
const account = await walletClient.requestAddresses()[0];

// Instantiate the Story Client for readonly operations, using default
// Instantiate the Story Client for readonly operations, using default
export const realonlyClient = StoryClient.newReadOnlyClient({});

// Instantiate the Story Client, test environment required for alpha release.
// The private key is also required for written operations.
export const client = StoryClient.newClient({account});
export const client = StoryClient.newClient({ account });
```

### Use `Client` or `ReadOnlyClient` to access Story Protocol
Expand All @@ -104,32 +107,40 @@ This section provides the instructions on how to build Story Protocol SDK from s

### Prerequisite

* Install PNPM: Execute `npm install -g pnpm`
* Install TypeScript: Run `pnpm add typescript -D`
* Install Yalc: Use `npm install -g yalc`
- Install PNPM: Execute `npm install -g pnpm`
- Install TypeScript: Run `pnpm add typescript -D`
- Install Yalc: Use `npm install -g yalc`

### Steps for Using Yalc for Local Testing of Core-SDK

For manual testing of the core-sdk, set up a separate web project. The guide below uses `yalc` to link the `core-sdk` locally, enabling its installation and import for testing.

Under the `typescript-sdk/packages/core-sdk` directory:
* Navigate to the `core-sdk` directory.
* Execute `npm run build` to build your latest code.
* Run `yalc publish`. You should see a message like `@story-protocol/core-sdk@<version> published in store.` (Note: The version number may vary).

- Navigate to the `core-sdk` directory.
- Execute `npm run build` to build your latest code.
- Run `yalc publish`. You should see a message like `@story-protocol/core-sdk@<version> published in store.` (Note: The version number may vary).

To set up your testing environment (e.g., a new Next.js project), use `yalc add @story-protocol/core-sdk@<version>` (ensure the version number is updated accordingly).
* Run `pnpm install`. This installs `@story-protocol/core-sdk@<version>` with your local changes.

- Run `pnpm install`. This installs `@story-protocol/core-sdk@<version>` with your local changes.

### Steps to Refresh the Changes

Under the `typescript-sdk/packages/core-sdk` directory:
* Execute `npm run build` to build your latest code.
* Run `yalc push`.

- Execute `npm run build` to build your latest code.
- Run `yalc push`.

In your testing environment:
* Run `yalc update` to pull the latest changes.

- Run `yalc update` to pull the latest changes.

## Steps to pull and compile latest smart contract ABIs (Currently pulls from the protocol-contracts `dev` branch)

Must have `solc` installed (https://docs.soliditylang.org/en/v0.8.9/installing-solidity.html)
* run `make compile_contracts`

- run `make compile_contracts`

## Release

Expand All @@ -149,4 +160,3 @@ Please make sure to update tests as appropriate.
[MIT License](/LICENSE.md)

## Contact Us

4 changes: 2 additions & 2 deletions packages/core-sdk/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import axios, { AxiosInstance } from "axios";
import { createPublicClient, createWalletClient, http, PublicClient, WalletClient } from "viem";
import { sepolia } from "viem/chains";
import * as dotenv from "dotenv";

import { StoryConfig, StoryReadOnlyConfig } from "./types/config";
Expand All @@ -23,6 +22,7 @@ import { LicenseClient } from "./resources/license";
import { RelationshipClient } from "./resources/relationship";
import { RelationshipTypeClient } from "./resources/relationshipType";
import { RelationshipTypeReadOnlyClient } from "./resources/relationshipTypeReadOnly";
import { chainStringToViemChain } from "./utils/utils";

if (typeof process !== "undefined") {
dotenv.config();
Expand Down Expand Up @@ -56,7 +56,7 @@ export class StoryClient {
this.isReadOnly = isReadOnly;

const clientConfig = {
chain: this.config.chain || sepolia,
chain: chainStringToViemChain(this.config.chainId || "sepolia"),
transport: this.config.transport || http(process.env.RPC_PROVIDER_URL),
};

Expand Down
2 changes: 1 addition & 1 deletion packages/core-sdk/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export { TransactionClient } from "./resources/transaction";
export { PlatformClient } from "./utils/platform";
export { AddressZero, HashZero } from "./constants/common";

export type { StoryConfig, StoryReadOnlyConfig } from "./types/config";
export type { StoryConfig, StoryReadOnlyConfig, SupportedChainIds } from "./types/config";
export type { Client, ReadOnlyClient } from "./types/client";
export type { Hex, TypedData } from "./types/common";

Expand Down
11 changes: 9 additions & 2 deletions packages/core-sdk/src/types/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { Account, Chain, Transport } from "viem";
import { Account, Transport } from "viem";

/**
* Supported chains. For convenience, both name or chain ID are supported.
*
* @public
*/
export type SupportedChainIds = "11155111" | "sepolia" | "1" | "mainnet";

/**
* Configuration for the SDK Client.
Expand All @@ -15,6 +22,6 @@ export interface StoryConfig extends StoryReadOnlyConfig {
* @public
*/
export interface StoryReadOnlyConfig {
readonly chain?: Chain;
readonly chainId?: SupportedChainIds;
readonly transport?: Transport;
}
24 changes: 23 additions & 1 deletion packages/core-sdk/src/utils/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import { Hash } from "viem/types/misc";
import { DecodeEventLogReturnType } from "viem/_types/utils/abi/decodeEventLog";
import { Abi, decodeEventLog, PublicClient, encodeAbiParameters, parseAbiParameters } from "viem";
import {
Abi,
decodeEventLog,
PublicClient,
encodeAbiParameters,
parseAbiParameters,
Chain,
} from "viem";
import { InferEventName } from "viem/types/contract";
import { mainnet, sepolia } from "viem/chains";

import { Hex, TypedData } from "../types/common";
import { DERIVATIVES_ALLOWED_OPTIONS, PARAMS_TAG } from "../constants/license";
import { SupportedChainIds } from "../types/config";

export function isIntegerString(s: string): boolean {
const num = Number(s);
Expand Down Expand Up @@ -177,3 +186,16 @@ export function paramsTagValueDecoder(paramTag: Hex, paramValue: unknown) {

return { tag: parsedTag, value, type };
}

export function chainStringToViemChain(chainId: SupportedChainIds): Chain {
switch (chainId) {
case "1":
case "mainnet":
return mainnet;
case "11155111":
case "sepolia":
return sepolia;
default:
throw new Error(`chainId ${chainId as string} not supported`);
}
}
3 changes: 1 addition & 2 deletions packages/core-sdk/test/integration/ipAsset.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect } from "chai";
import { StoryClient, StoryConfig, Client } from "../../src";
import { sepolia } from "viem/chains";
import { Hex, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";

Expand All @@ -10,7 +9,7 @@ describe("IP Asset Functions", () => {

before(function () {
const config: StoryConfig = {
chain: sepolia,
chainId: "sepolia",
transport: http(process.env.RPC_PROVIDER_URL),
account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex),
};
Expand Down
3 changes: 1 addition & 2 deletions packages/core-sdk/test/integration/ipOrg.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect } from "chai";
import { StoryClient, StoryConfig, Client } from "../../src";
import { sepolia } from "viem/chains";
import { Hex, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";

Expand All @@ -10,7 +9,7 @@ describe("IPOrg Functions", () => {

before(function () {
const config: StoryConfig = {
chain: sepolia,
chainId: "sepolia",
transport: http(process.env.RPC_PROVIDER_URL),
account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex),
};
Expand Down
3 changes: 1 addition & 2 deletions packages/core-sdk/test/integration/license.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { expect } from "chai";
import { StoryClient, StoryConfig, Client } from "../../src";
import { sepolia } from "viem/chains";
import { http, parseGwei, PrivateKeyAccount, stringToHex } from "viem";
import { privateKeyToAccount } from "viem/accounts";

Expand All @@ -19,7 +18,7 @@ describe("License Functions", () => {
wallet = privateKeyToAccount(process.env.WALLET_PRIVATE_KEY as `0x${string}`);

const config: StoryConfig = {
chain: sepolia,
chainId: "sepolia",
transport: http(process.env.RPC_PROVIDER_URL),
account: wallet,
};
Expand Down
3 changes: 1 addition & 2 deletions packages/core-sdk/test/integration/platform.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { expect } from "chai";
import { StoryClient, StoryConfig, Client } from "../../src";
import { createFileReaderMock } from "../unit/testUtils";
import { goerli } from "viem/chains";
import { Hex, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";

Expand All @@ -16,7 +15,7 @@ describe("Platform client integration tests", () => {

beforeEach(function () {
const config: StoryConfig = {
chain: goerli,
chainId: "sepolia",
transport: http(process.env.RPC_PROVIDER_URL),
account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex),
};
Expand Down
3 changes: 1 addition & 2 deletions packages/core-sdk/test/integration/relationship.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import { expect } from "chai";
import { StoryClient, StoryConfig, Client, RegisterRelationshipRequest } from "../../src";
import { privateKeyToAccount } from "viem/accounts";
import { Hex, http } from "viem";
import { sepolia } from "viem/chains";

describe("Relationship Functions", function () {
let client: Client;

before(function () {
const config: StoryConfig = {
chain: sepolia,
chainId: "sepolia",
transport: http(process.env.RPC_PROVIDER_URL),
account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex),
};
Expand Down
3 changes: 1 addition & 2 deletions packages/core-sdk/test/integration/relationshipType.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ import {
} from "../../src";
import { privateKeyToAccount } from "viem/accounts";
import { Hex, http } from "viem";
import { sepolia } from "viem/chains";

describe("Relationship Type Functions", function () {
let client: Client;

before(function () {
const config: StoryConfig = {
chain: sepolia,
chainId: "sepolia",
transport: http(process.env.RPC_PROVIDER_URL),
account: privateKeyToAccount((process.env.WALLET_PRIVATE_KEY || "0x") as Hex),
};
Expand Down
22 changes: 9 additions & 13 deletions packages/core-sdk/test/unit/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,19 @@ import { Account } from "viem";

describe("Test StoryClient", function () {
describe("Test constructor", function () {
it("should succeed when passing in valid params", function () {
try {
StoryClient.newClient({
account: privateKeyToAccount(generatePrivateKey()),
});
} catch (error) {
expect.fail(`Function should not have thrown any error, but it threw: ${error}`);
}
it("should succeed when passing in default params", function () {
const client = StoryClient.newClient({
account: privateKeyToAccount(generatePrivateKey()),
});
expect(client).to.be.instanceOf(StoryClient);
});

it("throw error when wallet account is null", function () {
try {
StoryClient.newClient({
it("should throw error when wallet account is null", function () {
expect(() => {
const client = StoryClient.newClient({
account: null as any as Account,
});
expect.fail(`Function should not get here, it should throw an error `);
} catch (error) {}
}).to.throw("account is null");
});
});

Expand Down
Loading
Loading