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

task(devx): Update TS SDK docs #3955

Merged
merged 23 commits into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d7b6070
task(devx): Updated BCS docs.
lucas-tortora Nov 7, 2024
1079582
task(devx): Updated dapp Kit docs.
lucas-tortora Nov 7, 2024
52a7350
task(devx): Updated kiosk docs.
lucas-tortora Nov 7, 2024
ca36871
task(devx): Updated ts docs. fix dead links and examples. imported ne…
lucas-tortora Nov 7, 2024
00bae2f
fix(devx): remove deprecated refs
lucas-tortora Nov 7, 2024
9d1a63f
fix(devx): fix links
lucas-tortora Nov 7, 2024
d8af3e4
task(devx): remove migration guide for kiosk
lucas-tortora Nov 8, 2024
07c1de4
Merge branch 'develop' into devx/update-ts-docs
lucas-tortora Nov 8, 2024
af90921
Apply suggestions from code review
lucas-tortora Nov 11, 2024
cb81451
fix(devx): replace tabs with 4 spaces
lucas-tortora Nov 12, 2024
1bc60fb
Apply suggestions from code review
lucas-tortora Nov 12, 2024
e0642d2
Merge remote-tracking branch 'origin/develop' into devx/update-ts-docs
lucas-tortora Nov 12, 2024
bb1a9c6
Apply suggestions from code review
lucas-tortora Nov 13, 2024
2d9d486
task(devx): Address comments from code review
lucas-tortora Nov 13, 2024
2bc28b7
fix(devx): replace `tx: tx` with `tx`
lucas-tortora Nov 13, 2024
d6a8f02
fix(devx) replace graphQL nameserver example
lucas-tortora Nov 13, 2024
8a5fb70
Merge branch 'develop' into devx/update-ts-docs
lucas-tortora Nov 13, 2024
e85476c
Merge branch 'develop' into devx/update-ts-docs
lucas-tortora Nov 15, 2024
8336bb3
Merge branch 'develop' into devx/update-ts-docs
lucas-tortora Nov 15, 2024
2248183
Merge branch 'develop' into devx/update-ts-docs
lucas-tortora Nov 15, 2024
959f050
Apply suggestions from code review
lucas-tortora Nov 15, 2024
2d1af9a
replace fromB64 with fromBase64 when it's from the utils package
lucas-tortora Nov 15, 2024
e048867
Merge branch 'develop' into devx/update-ts-docs
lucas-tortora Nov 15, 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
16 changes: 6 additions & 10 deletions docs/content/developer/standards/wallet-standard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ wallet adapter, you must implement the following features in your wallet:
for execution to the blockchain.
- `iota:reportTransactionEffects` - Use to report the effects of a transaction executed in the dApp
to the wallet. This allows the wallet to update its internal state to reflect the changes the transaction makes.
- `iota:signTransactionBlock` - The previous version of `iota:signTransaction`. Still
implemented for compatibility with dApps that have not updated to the new feature.
- `iota:signAndExecuteTransactionBlock` - The previous version of `iota:signAndExecuteTransaction`. Still implemented for compatibility with dApps that have not updated to the new feature.

Implement these features in your wallet class under the `features` property:

Expand Down Expand Up @@ -99,7 +96,7 @@ class YourWallet implements Wallet {
},
"iota:signAndExecuteTransaction": {
version: "2.0.0",
signAndExecuteTransaction: this.#signAndExecuteTransactionBlock,
signAndExecuteTransaction: this.#signAndExecuteTransaction,
},
"iota:reportTransactionEffects": {
version: "1.0.0",
Expand Down Expand Up @@ -160,8 +157,8 @@ class YourWallet implements Wallet {
// These features must exist on the wallet as well.
features: [
'iota:signPersonalMessage',
'iota:signTransactionBlock',
'iota:signAndExecuteTransactionBlock',
'iota:signTransaction',
'iota:signAndExecuteTransaction',
],
}),
);
Expand All @@ -182,10 +179,9 @@ registerWallet(new YourWallet());

### Best Practices for Efficient Transaction Execution

The Wallet standard has been updated from its original design to better support changes in the IOTA ecosystem. For example, the GraphQL service was introduced after Mainnet launched. The `iota:signAndExecuteTransactionBlock` feature is closely tied to the JSON RPC options and data structures, so its continued maintenance becomes increasingly difficult as the GraphQL service becomes more ubiquitous.

Consequently, the Wallet standard introduced the `iota:signAndExecuteTransaction` feature. The features of this method are more useful, regardless of which API you use to execute transactions. This usefulness comes at the expense
of flexibility in what `iota:signAndExecuteTransaction` returns.
The Wallet standard uses the `iota:signAndExecuteTransaction` feature.
The features of this method are useful, regardless of which API you use to execute transactions.
However, this usefulness comes at the expense of flexibility in what `iota:signAndExecuteTransaction` returns.

To solve this problem, use the `iota:signTransaction` feature to sign transactions, and
leave transaction execution to the dApp. The dApp can query for additional data during
Expand Down
29 changes: 17 additions & 12 deletions docs/content/references/ts-sdk/bcs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ npm i @iota/bcs
import { bcs } from '@iota/bcs';

// define UID as a 32-byte array, then add a transform to/from hex strings
const UID = bcs.array(32, bcs.u8()).transform({
const UID = bcs.fixedArray(32, bcs.u8()).transform({
input: (id: string) => fromHex(id),
output: (id) => toHex(id),
});
Expand Down Expand Up @@ -147,10 +147,15 @@ const struct = MyStruct.serialize({ id: 1, name: 'name' }).toBytes();
const tuple = bcs.tuple([bcs.u8(), bcs.string()]).serialize([1, 'name']).toBytes();

// Map
const map = bcs.map(bcs.u8(), bcs.string()).serialize(.toBytes()[
[1, 'one'],
[2, 'two'],
]);
const map = bcs
.map(bcs.u8(), bcs.string())
.serialize(
new Map([
[1, 'one'],
[2, 'two'],
]),
)
.toBytes();

// Parsing data back into original types

Expand Down Expand Up @@ -191,7 +196,7 @@ import { bcs, BcsType } from '@iota/bcs';

// The T typescript generic is a placeholder for the typescript type of the generic value
// The T argument will be the bcs type passed in when creating a concrete instance of the Container type
function Container<T>(T: BcsType<T>) {
function Container<T extends BcsType<any>>(T: T) {
return bcs.struct('Container<T>', {
contents: T,
}),
Expand All @@ -205,7 +210,7 @@ const U8Container = Container(bcs.u8());
const bytes = U8Container.serialize({ contents: 100 }).toBytes();

// Using multiple generics
function VecMap<K, V>(K: BcsType<K>, V: BcsType<V>) {
function VecMap<K extends BcsType<any>, V extends BcsType<any>>(K: K, V: V) {
// You can use the names of the generic params in the type name to
return bcs.struct(
// You can use the names of the generic params to give your type a more useful name
Expand Down Expand Up @@ -238,9 +243,9 @@ array. To handle this, you can use the `transform` API to map between the two fo

```ts
const Address = bcs.bytes(32).transform({
// To change the input type, you need to provide a type definition for the input
input: (val: string) => fromHEX(val),
output: (val) => toHEX(val),
// To change the input type, you need to provide a type definition for the input
input: (val: string) => fromHex(val),
output: (val) => toHex(val),
});

const serialized = Address.serialize('0x000000...').toBytes();
Expand Down Expand Up @@ -337,8 +342,8 @@ properties on a `BcsType`, or using the `InferBcsType` and `InferBcsInput` type
import { bcs, type InferBcsType, type InferBcsInput } from '@iota/bcs';

const MyStruct = bcs.struct('MyStruct', {
id: bcs.u64(),
name: bcs.string(),
id: bcs.u64(),
name: bcs.string(),
});

// using the $inferType and $inferInput properties
Expand Down
2 changes: 1 addition & 1 deletion docs/content/references/ts-sdk/dapp-kit/rpc-hooks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ function MyComponent() {
<Button
onClick={() => {
mutate({
transactionBlock: txb,
transaction: tx,
});
}}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# useReportTransactionEffects
lucas-tortora marked this conversation as resolved.
Show resolved Hide resolved

Use the `useReportTransactionEffects` hook can be used to report the effects of a transaction to the
connected wallet. The `useSignAndExecuteTransaction` hook automatically reports effects, and the
`useSignTransaction` hook provides a `reportTransactionEffects` callback to report effects manually,
so this hook is only needed when using a non-standard flow for executing transactions.

```ts live noInline
function withProviders(
Component: React.FunctionComponent<object>,
walletProviderProps?: Omit<ComponentProps<typeof WalletProvider>, 'children'>,
) {
// Work around server-side pre-rendering
const queryClient = new QueryClient();
const networks = {
mainnet: { url: getFullnodeUrl('mainnet') },
};

return () => {
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
setShouldRender(true);
}, [setShouldRender]);

if (!shouldRender) {
return null;
}

return (
<QueryClientProvider client={queryClient}>
<IotaClientProvider networks={networks}>
<WalletProvider {...walletProviderProps}>
<Component />
</WalletProvider>
</IotaClientProvider>
</QueryClientProvider>
);
};
}

function UseReportTransactionEffectsExample() {
const { mutateAsync: reportTransactionEffects } = useReportTransactionEffects();
const [signature, setSignature] = useState('');
const client = useSuiClient();
const currentAccount = useCurrentAccount();

return (
<div style={{ padding: 20 }}>
<ConnectButton />
{currentAccount && (
<>
<div>
<button
onClick={async () => {
const { effects } = await executePreSignedTransaction();
reportTransactionEffects({ effects });
}}
>
Sign empty transaction
</button>
</div>
<div>Signature: {signature}</div>
</>
)}
</div>
);
}

render(<UseReportTransactionEffectsExample/>)
```

## Arguments

- `effects`: The effects of an executed transaction. This can either be the `rawEffects` returned
from the JSON-RPC `executeTransaction` method (returned when showRawEffects is set to true),
or the `effects.bcs` when executing with the GraphQL API.
- `chain`: (optional) The chain identifier the transaction was executed on.
- `account` (optional) the account that signed the transaction, defaults to the currently connected
account
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
# useSignAndExecuteTransaction
lucas-tortora marked this conversation as resolved.
Show resolved Hide resolved

Use the `useSignAndExecuteTransaction` hook to prompt the user to sign and execute a transaction
block with their wallet.
lucas-tortora marked this conversation as resolved.
Show resolved Hide resolved

```ts live noInline
function withProviders(
Component: React.FunctionComponent<object>,
walletProviderProps?: Omit<ComponentProps<typeof WalletProvider>, 'children'>,
) {
// Work around server-side pre-rendering
const queryClient = new QueryClient();
const networks = {
mainnet: { url: getFullnodeUrl('mainnet') },
lucas-tortora marked this conversation as resolved.
Show resolved Hide resolved
};

return () => {
const [shouldRender, setShouldRender] = useState(false);
useEffect(() => {
setShouldRender(true);
}, [setShouldRender]);

if (!shouldRender) {
return null;
}

return (
<QueryClientProvider client={queryClient}>
<IotaClientProvider networks={networks}>
<WalletProvider {...walletProviderProps}>
<Component />
</WalletProvider>
</IotaClientProvider>
</QueryClientProvider>
);
};
}

const UseSignAndExecuteTransactionExample = withProviders(() => {
const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction();
const [digest, setDigest] = useState('');
const currentAccount = useCurrentAccount();

return (
<div style={{ padding: 20 }}>
<ConnectButton />
{currentAccount && (
<>
<div>
<button
onClick={() => {
signAndExecuteTransaction(
{
transaction: new Transaction(),
chain: 'iota:devnet',
},
{
onSuccess: (result) => {
console.log('executed transaction', result);
setDigest(result.digest);
},
},
);
}}
>
Sign and execute transaction
</button>
</div>
<div>Digest: {digest}</div>
</>
)}
</div>
);
});

render(<UseSignAndExecuteTransactionExample/>)
```

## Return additional data, or executing through GraphQL
lucas-tortora marked this conversation as resolved.
Show resolved Hide resolved

To customize how transactions are executed, and what data is returned when executing a transaction,
you can pass a custom `execute` function.

```ts
import {
ConnectButton,
useIotaClient,
useCurrentAccount,
useSignAndExecuteTransaction,
} from '@iota/dapp-kit';
import { useState } from 'react';

function MyComponent() {
const client = useIotaClient();
const { mutate: signAndExecuteTransaction } = useSignAndExecuteTransaction({
execute: async ({ bytes, signature }) =>
await client.executeTransactionBlock({
transactionBlock: bytes,
signature,
options: {
// Raw effects are required so the effects can be reported back to the wallet
showRawEffects: true,
// Select additional data to return
showObjectChanges: true,
},
}),
});

const [digest, setDigest] = useState('');
const currentAccount = useCurrentAccount();

return (
<div style={{ padding: 20 }}>
<ConnectButton />
{currentAccount && (
<>
<div>
<button
onClick={() => {
signAndExecuteTransaction(
{
transaction: new Transaction(),
chain: 'iota:devnet',
},
{
onSuccess: (result) => {
console.log('object changes', result.objectChanges);
setDigest(result.digest);
},
},
);
}}
>
Sign and execute transaction
</button>
</div>
<div>Digest: {digest}</div>
</>
)}
</div>
);
}
```

## Arguments

- `transaction`: The transaction to sign and execute.
- `chain`: (optional) The chain identifier the transaction should be signed for.
- `execute`: (optional) A custom function to execute the transaction

In addition to these options, you can also pass any options that the
[IotaClient.signAndExecuteTransaction](../../api/client/classes/IotaClient.md#signandexecutetransaction)
method accepts.
Loading
Loading