Skip to content

Commit

Permalink
Add migration guide (#17891)
Browse files Browse the repository at this point in the history
## Description 

Describe the changes or additions included in this PR.

## Test plan 

How did you test the new or updated feature?

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
  • Loading branch information
hayes-mysten committed May 28, 2024
1 parent aed4145 commit 1e05f91
Show file tree
Hide file tree
Showing 42 changed files with 1,036 additions and 189 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { DryRunTransactionBlockResponse } from '@mysten/sui/src/client';
import { DryRunTransactionBlockResponse } from '@mysten/sui/client';
import * as Tabs from '@radix-ui/react-tabs';
import { useState } from 'react';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0
import { useSuiClientContext } from '@mysten/dapp-kit';
import { ObjectOwner, SuiObjectChange } from '@mysten/sui/src/client';
import { ObjectOwner, SuiObjectChange } from '@mysten/sui/client';
import { CheckIcon, CopyIcon } from 'lucide-react';
import { useState } from 'react';
import toast from 'react-hot-toast';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { ObjectOwner } from '@mysten/sui/src/client';
import { ObjectOwner } from '@mysten/sui/client';
import { ReactNode } from 'react';

import { ObjectLink } from './ObjectLink';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { useSuiClientQuery } from '@mysten/dapp-kit';
import { type BalanceChange } from '@mysten/sui/src/client';
import { type BalanceChange } from '@mysten/sui/client';

import { PreviewCard } from '../PreviewCard';
import { onChainAmountToFloat } from '../utils';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { SuiEvent } from '@mysten/sui/src/client';
import { SuiEvent } from '@mysten/sui/client';
import { ReactNode } from 'react';

import { Textarea } from '@/components/ui/textarea';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import { SuiObjectChange } from '@mysten/sui/src/client';
import { SuiObjectChange } from '@mysten/sui/client';

import { ObjectLink } from '../ObjectLink';
import { PreviewCard } from '../PreviewCard';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

import { useSuiClientContext } from '@mysten/dapp-kit';
import { DryRunTransactionBlockResponse, GasCostSummary } from '@mysten/sui/src/client';
import { DryRunTransactionBlockResponse, GasCostSummary } from '@mysten/sui/client';
import { ReactNode } from 'react';

import { ObjectLink } from '../ObjectLink';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import {
SuiArgument,
SuiCallArg,
SuiTransaction,
TransactionBlockData,
} from '@mysten/sui/src/client';
import { SuiArgument, SuiCallArg, SuiTransaction, TransactionBlockData } from '@mysten/sui/client';
import { ReactNode } from 'react';

import { ObjectLink } from '../ObjectLink';
Expand Down
18 changes: 9 additions & 9 deletions sdk/dapp-kit/src/components/WalletProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import type { StateStorage } from 'zustand/middleware';

import {
DEFAULT_PREFERRED_WALLETS,
DEFAULT_REQUIRED_FEATURES,
DEFAULT_STORAGE,
DEFAULT_STORAGE_KEY,
DEFAULT_WALLET_FILTER,
} from '../constants/walletDefaults.js';
import { WalletContext } from '../contexts/walletContext.js';
import { useAutoConnectWallet } from '../hooks/wallet/useAutoConnectWallet.js';
Expand All @@ -30,8 +30,8 @@ export type WalletProviderProps = {
/** A list of wallets that are sorted to the top of the wallet list, if they are available to connect to. By default, wallets are sorted by the order they are loaded in. */
preferredWallets?: string[];

/** A list of features that are required for the dApp to function. This filters the list of wallets presented to users when selecting a wallet to connect from, ensuring that only wallets that meet the dApps requirements can connect. */
requiredFeatures?: (keyof WalletWithRequiredFeatures['features'])[];
/** A filter function to select wallets that support features required for the dApp to function. This filters the list of wallets presented to users when selecting a wallet to connect from, ensuring that only wallets that meet the dApps requirements can connect. */
walletFilter?: (wallet: WalletWithRequiredFeatures) => boolean;

/** Enables the development-only unsafe burner wallet, which can be useful for testing. */
enableUnsafeBurner?: boolean;
Expand All @@ -58,7 +58,7 @@ export type { WalletWithFeatures };

export function WalletProvider({
preferredWallets = DEFAULT_PREFERRED_WALLETS,
requiredFeatures = DEFAULT_REQUIRED_FEATURES,
walletFilter = DEFAULT_WALLET_FILTER,
storage = DEFAULT_STORAGE,
storageKey = DEFAULT_STORAGE_KEY,
enableUnsafeBurner = false,
Expand All @@ -70,7 +70,7 @@ export function WalletProvider({
const storeRef = useRef(
createWalletStore({
autoConnectEnabled: autoConnect,
wallets: getRegisteredWallets(preferredWallets, requiredFeatures),
wallets: getRegisteredWallets(preferredWallets, walletFilter),
storage: storage || createInMemoryStore(),
storageKey,
}),
Expand All @@ -80,7 +80,7 @@ export function WalletProvider({
<WalletContext.Provider value={storeRef.current}>
<WalletConnectionManager
preferredWallets={preferredWallets}
requiredFeatures={requiredFeatures}
walletFilter={walletFilter}
enableUnsafeBurner={enableUnsafeBurner}
stashedWallet={stashedWallet}
>
Expand All @@ -94,17 +94,17 @@ export function WalletProvider({

type WalletConnectionManagerProps = Pick<
WalletProviderProps,
'preferredWallets' | 'requiredFeatures' | 'enableUnsafeBurner' | 'stashedWallet' | 'children'
'preferredWallets' | 'walletFilter' | 'enableUnsafeBurner' | 'stashedWallet' | 'children'
>;

function WalletConnectionManager({
preferredWallets = DEFAULT_PREFERRED_WALLETS,
requiredFeatures = DEFAULT_REQUIRED_FEATURES,
walletFilter = DEFAULT_WALLET_FILTER,
enableUnsafeBurner = false,
stashedWallet,
children,
}: WalletConnectionManagerProps) {
useWalletsChanged(preferredWallets, requiredFeatures);
useWalletsChanged(preferredWallets, walletFilter);
useWalletPropertiesChanged();
useStashedWallet(stashedWallet);
useUnsafeBurnerWallet(enableUnsafeBurner);
Expand Down
10 changes: 7 additions & 3 deletions sdk/dapp-kit/src/constants/walletDefaults.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

import type { WalletWithRequiredFeatures } from '@mysten/wallet-standard';
import type { SuiWalletFeatures, WalletWithRequiredFeatures } from '@mysten/wallet-standard';
import { STASHED_WALLET_NAME } from '@mysten/zksend';

import { createInMemoryStore } from '../utils/stateStorage.js';
Expand All @@ -13,8 +13,12 @@ export const DEFAULT_STORAGE =

export const DEFAULT_STORAGE_KEY = 'sui-dapp-kit:wallet-connection-info';

export const DEFAULT_REQUIRED_FEATURES: (keyof WalletWithRequiredFeatures['features'])[] = [
const SIGN_FEATURES = [
'sui:signTransaction',
];
'sui:signTransactionBlock',
] satisfies (keyof SuiWalletFeatures)[];

export const DEFAULT_WALLET_FILTER = (wallet: WalletWithRequiredFeatures) =>
SIGN_FEATURES.some((feature) => wallet.features[feature]);

export const DEFAULT_PREFERRED_WALLETS = [SUI_WALLET_NAME, STASHED_WALLET_NAME];
10 changes: 5 additions & 5 deletions sdk/dapp-kit/src/hooks/wallet/useWalletsChanged.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ import { useWalletStore } from './useWalletStore.js';
*/
export function useWalletsChanged(
preferredWallets: string[],
requiredFeatures: (keyof WalletWithRequiredFeatures['features'])[],
walletFilter?: (wallet: WalletWithRequiredFeatures) => boolean,
) {
const setWalletRegistered = useWalletStore((state) => state.setWalletRegistered);
const setWalletUnregistered = useWalletStore((state) => state.setWalletUnregistered);

useEffect(() => {
const walletsApi = getWallets();
setWalletRegistered(getRegisteredWallets(preferredWallets, requiredFeatures));
setWalletRegistered(getRegisteredWallets(preferredWallets, walletFilter));

const unsubscribeFromRegister = walletsApi.on('register', () => {
setWalletRegistered(getRegisteredWallets(preferredWallets, requiredFeatures));
setWalletRegistered(getRegisteredWallets(preferredWallets, walletFilter));
});

const unsubscribeFromUnregister = walletsApi.on('unregister', (unregisteredWallet) => {
setWalletUnregistered(
getRegisteredWallets(preferredWallets, requiredFeatures),
getRegisteredWallets(preferredWallets, walletFilter),
unregisteredWallet,
);
});
Expand All @@ -37,5 +37,5 @@ export function useWalletsChanged(
unsubscribeFromRegister();
unsubscribeFromUnregister();
};
}, [preferredWallets, requiredFeatures, setWalletRegistered, setWalletUnregistered]);
}, [preferredWallets, walletFilter, setWalletRegistered, setWalletUnregistered]);
}
5 changes: 3 additions & 2 deletions sdk/dapp-kit/src/utils/walletUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,20 @@ import type {
MinimallyRequiredFeatures,
Wallet,
WalletWithFeatures,
WalletWithRequiredFeatures,
} from '@mysten/wallet-standard';
import { getWallets, isWalletWithRequiredFeatureSet } from '@mysten/wallet-standard';

export function getRegisteredWallets<AdditionalFeatures extends Wallet['features']>(
preferredWallets: string[],
requiredFeatures?: (keyof AdditionalFeatures)[],
walletFilter?: (wallet: WalletWithRequiredFeatures) => boolean,
) {
const walletsApi = getWallets();
const wallets = walletsApi.get();

const suiWallets = wallets.filter(
(wallet): wallet is WalletWithFeatures<MinimallyRequiredFeatures & AdditionalFeatures> =>
isWalletWithRequiredFeatureSet(wallet, requiredFeatures),
isWalletWithRequiredFeatureSet(wallet) && (!walletFilter || walletFilter(wallet)),
);

return [
Expand Down
2 changes: 1 addition & 1 deletion sdk/dapp-kit/test/components/WalletProvider.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ describe('WalletProvider', () => {
const { unregister: unregister2 } = registerMockWallet({ walletName: 'Mock Wallet 2' });

const wrapper = createWalletProviderContextWrapper({
requiredFeatures: ['my-dapp:super-cool-feature'],
walletFilter: (wallet) => !!wallet.features['my-dapp:super-cool-feature'],
});
const { result } = renderHook(() => useWallets(), { wrapper });
const walletNames = result.current.map((wallet) => wallet.name);
Expand Down
4 changes: 2 additions & 2 deletions sdk/docs/pages/dapp-kit/wallet-provider.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ to other dApp Kit hooks and components.
All props are optional.

- `preferredWallets` - A list of wallets that are sorted to the top of the wallet list.
- `requiredFeatures` - A list of features that are required for the dApp to function. This filters
the list of wallets presented to users when selecting a wallet to connect from, ensuring that only
- `walletFilter` - A filter function that accepts a wallet and returns a boolean. This filters the
list of wallets presented to users when selecting a wallet to connect from, ensuring that only
wallets that meet the dApp requirements can connect.
- `enableUnsafeBurner` - Enables the development-only unsafe burner wallet, useful for testing.
- `autoConnect` - Enables automatically reconnecting to the most recently used wallet account upon
Expand Down
6 changes: 5 additions & 1 deletion sdk/docs/pages/typescript/_meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
"hello-sui": "Hello, Sui",
"faucet": "Faucet",
"sui-client": "SuiClient",
"graphql": "SuiGraphQLClient",
"transaction-building": "Transaction Building",
"cryptography": "Cryptography",
"utils": "Utils",
"bcs": "BCS",
"zklogin": "ZKLogin",
"executors": "Transaction Executors",
"plugins": "Plugins",
"owned-object-pool": "Owned Object Pool",
"executors": "Transaction Executors"
"migrations": "Migrations"
}
93 changes: 93 additions & 0 deletions sdk/docs/pages/typescript/graphql.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# SuiGraphQLClient

import { Callout } from 'nextra/components';

<Callout type="warning">
SuiGraphQLClient is still in development and may change rapidly as it is being developed.
</Callout>

To support GraphQL Queries, the Typescript SDK includes the `SuiGraphQLClient` which can help you
write and execute GraphQL queries against the Sui GraphQL API that are type-safe and easy to use.

## Writing your first query

We'll start by creating our client, and executing a very basic query:

```typescript
import { SuiGraphQLClient } from '@mysten/sui/graphql';
import { graphql } from '@mysten/sui/graphql/schemas/2024.4';

const gqlClient = new SuiGraphQLClient({
url: 'https://sui-testnet.mystenlabs.com/graphql',
});

const chainIdentifierQuery = graphql(`
query {
chainIdentifier
}
`);

async function getChainIdentifier() {
const result = await gqlClient.query({
query: chainIdentifierQuery,
});

return result.data?.chainIdentifier;
}
```

## Type-safety for GraphQL queries

You may have noticed the example above does not include any type definitions for the query. The
`graphql` function used in the example is powered by [`gql.tada`](https://gql-tada.0no.co/) and will
automatically provide the required type information to ensure that your queries are properly typed
when executed through `SuiGraphQLClient`.

The `graphql` function itself is imported from a versioned schema file, and you should ensure that
you are using the version that corresponds to the latest release of the GraphQL API.

The `graphql` also detects variables used by your query, and will ensure that the variables passed
to your query are properly typed.

```typescript
const getSuinsName = graphql(`
query getSuiName($address: SuiAddress!) {
address(address: $address) {
defaultSuinsName
}
}
`);

async function getDefaultSuinsName(address: string) {
const result = await gqlClient.query({
query: getSuinsName,
variables: {
address,
},
});

return result.data?.address?.defaultSuinsName;
}
```

## Using typed GraphQL queries with other GraphQL clients

The `graphql` function returns document nodes that implement the
[TypedDocumentNode](https://github.com/dotansimha/graphql-typed-document-node) standard, and will
work with the majority of popular GraphQL clients to provide queries that are automatically typed.

```typescript
import { useQuery } from '@apollo/client';

const chainIdentifierQuery = graphql(`
query {
chainIdentifier
}
`);

function ChainIdentifier() {
const { loading, error, data } = useQuery(getPokemonsQuery);

return <div>{data?.chainIdentifier}</div>;
}
```
3 changes: 3 additions & 0 deletions sdk/docs/pages/typescript/migrations/_meta.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"sui-1.0": "@mysten/sui v1.0"
}
Loading

0 comments on commit 1e05f91

Please sign in to comment.