diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d167274ba22..cb9e88a224c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1471,9 +1471,6 @@ importers:
'@iota/wallet-standard':
specifier: workspace:*
version: link:../wallet-standard
- '@iota/zksend':
- specifier: workspace:*
- version: link:../zksend
'@radix-ui/react-dialog':
specifier: ^1.0.4
version: 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)
@@ -1947,37 +1944,6 @@ importers:
specifier: ^0.33.0
version: 0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0)
- sdk/zksend:
- dependencies:
- '@iota/iota.js':
- specifier: workspace:*
- version: link:../typescript
- '@iota/wallet-standard':
- specifier: workspace:*
- version: link:../wallet-standard
- mitt:
- specifier: ^3.0.1
- version: 3.0.1
- nanostores:
- specifier: ^0.9.3
- version: 0.9.3
- valibot:
- specifier: ^0.25.0
- version: 0.25.0
- devDependencies:
- '@iota/build-scripts':
- specifier: workspace:*
- version: link:../build-scripts
- '@types/node':
- specifier: ^20.4.2
- version: 20.4.2
- typescript:
- specifier: ^5.3.3
- version: 5.3.3
- vitest:
- specifier: ^0.33.0
- version: 0.33.0(@vitest/ui@0.33.0)(happy-dom@10.5.1)(jsdom@23.0.0)(sass@1.63.6)(terser@5.31.0)
-
packages:
'@0no-co/graphql.web@1.0.7':
@@ -14423,9 +14389,6 @@ packages:
resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
engines: {node: '>=10.12.0'}
- valibot@0.25.0:
- resolution: {integrity: sha512-cmD0ca15oyAbT75iYLNW6uU6doAeIwYfOshpXka/E1Bx4frzbkrgb7gvkI7K0YK/DVOksei4FfxWfRoBP3NFTg==}
-
validate-npm-package-license@3.0.4:
resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==}
@@ -31401,8 +31364,6 @@ snapshots:
'@types/istanbul-lib-coverage': 2.0.4
convert-source-map: 1.9.0
- valibot@0.25.0: {}
-
validate-npm-package-license@3.0.4:
dependencies:
spdx-correct: 3.2.0
diff --git a/sdk/dapp-kit/package.json b/sdk/dapp-kit/package.json
index d1958878003..6085fbd7674 100644
--- a/sdk/dapp-kit/package.json
+++ b/sdk/dapp-kit/package.json
@@ -81,7 +81,6 @@
"dependencies": {
"@iota/iota.js": "workspace:*",
"@iota/wallet-standard": "workspace:*",
- "@iota/zksend": "workspace:*",
"@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-dropdown-menu": "^2.0.5",
"@radix-ui/react-slot": "^1.0.2",
diff --git a/sdk/dapp-kit/src/components/WalletProvider.tsx b/sdk/dapp-kit/src/components/WalletProvider.tsx
index 67a68400bb9..0dae6322522 100644
--- a/sdk/dapp-kit/src/components/WalletProvider.tsx
+++ b/sdk/dapp-kit/src/components/WalletProvider.tsx
@@ -18,8 +18,6 @@ import { useAutoConnectWallet } from '../hooks/wallet/useAutoConnectWallet.js';
import { useUnsafeBurnerWallet } from '../hooks/wallet/useUnsafeBurnerWallet.js';
import { useWalletPropertiesChanged } from '../hooks/wallet/useWalletPropertiesChanged.js';
import { useWalletsChanged } from '../hooks/wallet/useWalletsChanged.js';
-import type { ZkSendWalletConfig } from '../hooks/wallet/useZkSendWallet.js';
-import { useZkSendWallet } from '../hooks/wallet/useZkSendWallet.js';
import { lightTheme } from '../themes/lightTheme.js';
import type { Theme } from '../themes/themeContract.js';
import { createInMemoryStore } from '../utils/stateStorage.js';
@@ -40,9 +38,6 @@ export type WalletProviderProps = {
/** Enables automatically reconnecting to the most recently used wallet account upon mounting. */
autoConnect?: boolean;
- /** Enables the zkSend wallet */
- zkSend?: ZkSendWalletConfig;
-
/** Configures how the most recently connected to wallet account is stored. Set to `null` to disable persisting state entirely. Defaults to using localStorage if it is available. */
storage?: StateStorage | null;
@@ -64,7 +59,6 @@ export function WalletProvider({
storageKey = DEFAULT_STORAGE_KEY,
enableUnsafeBurner = false,
autoConnect = false,
- zkSend,
theme = lightTheme,
children,
}: WalletProviderProps) {
@@ -83,7 +77,6 @@ export function WalletProvider({
preferredWallets={preferredWallets}
requiredFeatures={requiredFeatures}
enableUnsafeBurner={enableUnsafeBurner}
- zkSend={zkSend}
>
{/* TODO: We ideally don't want to inject styles if people aren't using the UI components */}
{theme ? : null}
@@ -95,19 +88,17 @@ export function WalletProvider({
type WalletConnectionManagerProps = Pick<
WalletProviderProps,
- 'preferredWallets' | 'requiredFeatures' | 'enableUnsafeBurner' | 'zkSend' | 'children'
+ 'preferredWallets' | 'requiredFeatures' | 'enableUnsafeBurner' | 'children'
>;
function WalletConnectionManager({
preferredWallets = DEFAULT_PREFERRED_WALLETS,
requiredFeatures = DEFAULT_REQUIRED_FEATURES,
enableUnsafeBurner = false,
- zkSend,
children,
}: WalletConnectionManagerProps) {
useWalletsChanged(preferredWallets, requiredFeatures);
useWalletPropertiesChanged();
- useZkSendWallet(zkSend);
useUnsafeBurnerWallet(enableUnsafeBurner);
useAutoConnectWallet();
diff --git a/sdk/dapp-kit/src/constants/walletDefaults.ts b/sdk/dapp-kit/src/constants/walletDefaults.ts
index 2882bc860ad..be739763898 100644
--- a/sdk/dapp-kit/src/constants/walletDefaults.ts
+++ b/sdk/dapp-kit/src/constants/walletDefaults.ts
@@ -3,7 +3,6 @@
// SPDX-License-Identifier: Apache-2.0
import type { WalletWithRequiredFeatures } from '@iota/wallet-standard';
-import { ZKSEND_WALLET_NAME } from '@iota/zksend';
import { createInMemoryStore } from '../utils/stateStorage.js';
@@ -18,4 +17,4 @@ export const DEFAULT_REQUIRED_FEATURES: (keyof WalletWithRequiredFeatures['featu
'iota:signTransactionBlock',
];
-export const DEFAULT_PREFERRED_WALLETS = [IOTA_WALLET_NAME, ZKSEND_WALLET_NAME];
+export const DEFAULT_PREFERRED_WALLETS = [IOTA_WALLET_NAME];
diff --git a/sdk/dapp-kit/src/hooks/wallet/useZkSendWallet.ts b/sdk/dapp-kit/src/hooks/wallet/useZkSendWallet.ts
deleted file mode 100644
index 9146b464619..00000000000
--- a/sdk/dapp-kit/src/hooks/wallet/useZkSendWallet.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import type { ZkSendWallet } from '@iota/zksend';
-import { registerZkSendWallet } from '@iota/zksend';
-import { useEffect, useLayoutEffect, useState } from 'react';
-
-import { useAutoConnectWallet } from './useAutoConnectWallet.js';
-import { useConnectWallet } from './useConnectWallet.js';
-
-export interface ZkSendWalletConfig {
- name: string;
- origin?: string;
-}
-
-export function useZkSendWallet(config?: ZkSendWalletConfig) {
- const status = useAutoConnectWallet();
- const [address, setAddress] = useState(null);
- const [wallet, setWallet] = useState(null);
- const { mutate: connect } = useConnectWallet();
-
- useEffect(() => {
- // This handles an edge case where the user has already connected a wallet, but is coming from
- // a zkSend redirect, and we want to force the zkSend wallet to connect. We need to wait for the
- // autoconnection to attempt to connect, then force the zkSend wallet to connect.
- if (!address || !wallet || status !== 'attempted') return;
-
- connect({ wallet, silent: true });
- // Reset the address since we only want to do this once:
- setAddress(null);
- }, [address, status, connect, wallet]);
-
- useLayoutEffect(() => {
- if (!config?.name) {
- return;
- }
-
- const { wallet, unregister, addressFromRedirect } = registerZkSendWallet(config.name, {
- origin: config.origin,
- });
-
- if (addressFromRedirect) {
- setWallet(wallet);
- setAddress(addressFromRedirect);
- }
-
- return unregister;
- }, [config?.name, config?.origin]);
-}
diff --git a/sdk/dapp-kit/tsconfig.json b/sdk/dapp-kit/tsconfig.json
index 4e05676fad3..09c39c9c544 100644
--- a/sdk/dapp-kit/tsconfig.json
+++ b/sdk/dapp-kit/tsconfig.json
@@ -8,9 +8,5 @@
"jsx": "react-jsx",
"rootDir": "src"
},
- "references": [
- { "path": "../typescript" },
- { "path": "../wallet-standard" },
- { "path": "../zksend" }
- ]
+ "references": [{ "path": "../typescript" }, { "path": "../wallet-standard" }]
}
diff --git a/sdk/docs/package.json b/sdk/docs/package.json
index 722f55ff6a3..e120bc08c35 100644
--- a/sdk/docs/package.json
+++ b/sdk/docs/package.json
@@ -31,7 +31,6 @@
"@iota/kiosk": "workspace:*",
"@iota/iota.js": "workspace:*",
"@iota/zklogin": "workspace:*",
- "@iota/zksend": "workspace:*",
"@tanstack/react-query": "^5.0.0",
"@types/node": "^20.4.2",
"next": "^13.4.15",
diff --git a/sdk/docs/pages/_meta.json b/sdk/docs/pages/_meta.json
index 2e75fbf36a8..7f14db0df0e 100644
--- a/sdk/docs/pages/_meta.json
+++ b/sdk/docs/pages/_meta.json
@@ -11,10 +11,6 @@
"title": "Kiosk SDK",
"type": "page"
},
- "zksend": {
- "title": "zkSend SDK",
- "type": "page"
- },
"bcs": {
"title": "BCS",
"type": "page"
diff --git a/sdk/docs/pages/dapp-kit/_meta.json b/sdk/docs/pages/dapp-kit/_meta.json
index 70b776784d0..1c16272071a 100644
--- a/sdk/docs/pages/dapp-kit/_meta.json
+++ b/sdk/docs/pages/dapp-kit/_meta.json
@@ -6,6 +6,5 @@
"wallet-provider": "WalletProvider",
"wallet-components": "Wallet Components",
"wallet-hooks": "Wallet Hooks",
- "zksend": "zkSend Integration",
"themes": "Themes"
}
diff --git a/sdk/docs/pages/dapp-kit/wallet-provider.mdx b/sdk/docs/pages/dapp-kit/wallet-provider.mdx
index 9038c0fcd44..3222ebfe68b 100644
--- a/sdk/docs/pages/dapp-kit/wallet-provider.mdx
+++ b/sdk/docs/pages/dapp-kit/wallet-provider.mdx
@@ -29,8 +29,6 @@ All props are optional.
- `enableUnsafeBurner` - Enables the development-only unsafe burner wallet, useful for testing.
- `autoConnect` - Enables automatically reconnecting to the most recently used wallet account upon
mounting.
-- `zkSend` - Enables and configures the zkSend wallet. Read more about how to
- [use the zkSend integration](./zksend.mdx).
- `storage` - Configures how the most recently connected-to wallet account is stored. Set to
`null` to disable persisting state entirely. Defaults to using `localStorage` if it is
available.
diff --git a/sdk/docs/pages/dapp-kit/zksend.mdx b/sdk/docs/pages/dapp-kit/zksend.mdx
deleted file mode 100644
index 3a6d794bbe3..00000000000
--- a/sdk/docs/pages/dapp-kit/zksend.mdx
+++ /dev/null
@@ -1,24 +0,0 @@
-# zkSend Integration
-
-dApp Kit provides out-of-the-box opt-in support for [zkSend wallets](../zksend/dapp.mdx).
-
-## Setup
-
-To enable support for zkSend wallets, pass the `zkSend` object to the `WalletProvider` component.
-This object has the following properties:
-
-- **`name`** - The name of your dApp, shown to the user when connecting to the dApp.
-
-```tsx
-function App({ children }) {
- return (
-
- {children}
-
- );
-}
-```
diff --git a/sdk/docs/pages/zksend/_meta.json b/sdk/docs/pages/zksend/_meta.json
deleted file mode 100644
index b32e4c426d1..00000000000
--- a/sdk/docs/pages/zksend/_meta.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "index": "Introduction",
- "dapp": "dApp Integration",
- "link-builder": "Creating zkSend Links"
-}
diff --git a/sdk/docs/pages/zksend/dapp.mdx b/sdk/docs/pages/zksend/dapp.mdx
deleted file mode 100644
index 19af5a00e5c..00000000000
--- a/sdk/docs/pages/zksend/dapp.mdx
+++ /dev/null
@@ -1,73 +0,0 @@
-import { Callout } from 'nextra/components';
-
-# dApp Integration
-
-
- If you are using `dapp-kit`, you do not need to install any additional packages to integrate
- with the zkSend wallet. [Read how to integrate with dapp-kit.](../dapp-kit/zksend.mdx)
-
-
-Using the zkSend SDK, you can allow users to connect to the zkSend wallet from your dApp. The wallet
-is provided through the [Wallet Standard](https://docs.iota.io/standards/wallet-standard), and should
-appear automatically in your existing wallet connection UI.
-
-## Considerations
-
-- zkSend only supports mainnet at this time.
-- Users will only be able to connect their zkLogin wallet from zkSend.
-- The zkLogin account will be managed by zkSend, you do not need to set up any OAuth providers.
-- You will not get access to the user's private key, you will only be able to connect to the
- wallet, and suggest transactions and messages to sign, just like any other wallet in the
- ecosystem.
-
-## Setup
-
-To use the zkSend wallet, you will need to register it in your application, using
-`registerZkSendWallet`. This only needs to be done once, and should be done as early as possible in
-your application's lifecycle.
-
-`registerZkSendWallet` takes two arguments:
-
-- `name`: The name of your dApp. This will be shown to the user when they are asked to approve the
- connection in zkSend.
-- `options`: An optional object with the following properties:
- - `origin`: The origin of the zkSend website. Defaults to `https://zksend.com`.
-
-```ts
-import { registerZkSendWallet } from '@iota/zksend';
-
-registerZkSendWallet('Your dApp Name');
-```
-
-## Supported features
-
-The zkSend wallet currently supports the following features:
-
-- `signTransactionBlock`
-- `signPersonalMessage`
-
-We intentionally do not support `signAndExecuteTransactionBlock`, and suggest that your dApp instead
-use `signTransactionBlock`, and submit the signed transaction within your dApp instead. This
-provides better control around execution, and avoids potential issues around data inconsistency. If
-you believe you have a strong reason for using `signAndExecuteTransactionBlock`, please
-[open an issue](https://github.com/iotaledger/iota/issues/new/choose).
-
-## Detecting the zkSend wallet
-
-If you'd like to detect whether the user is connected to the zkSend wallet, you can use the `name`
-property on the wallet
-
-For example, if you are using `dapp-kit`, you can use the `useCurrentWallet` hook to get the current
-wallet, and check if it is the zkSend wallet.
-
-```ts
-import { useCurrentWallet } from '@iota/dapp-kit';
-import { ZKSEND_WALLET_NAME } from '@iota/zksend';
-
-function ZkSendOnly() {
- const { curentWallet } = useCurrentWallet();
- const walletIsZkSendWallet = curentWallet?.name === ZKSEND_WALLET_NAME;
-
- // rest of component logic...
-}
-```
diff --git a/sdk/docs/pages/zksend/index.mdx b/sdk/docs/pages/zksend/index.mdx
deleted file mode 100644
index 15b6a9dc161..00000000000
--- a/sdk/docs/pages/zksend/index.mdx
+++ /dev/null
@@ -1,12 +0,0 @@
-# zkSend SDK
-
-The zkSend SDK provides tools for interacting with the [zkSend website](https://zksend.com). It
-allows dApps to integrate zkSend into their applications by providing a standard wallet interface.
-It also provides functionality to create your own zkSend Claim Links, with support for any publicly
-transferrable asset.
-
-## Installation
-
-```sh npm2yarn
-npm i @iota/zksend
-```
diff --git a/sdk/docs/pages/zksend/link-builder.mdx b/sdk/docs/pages/zksend/link-builder.mdx
deleted file mode 100644
index 2a1586dd579..00000000000
--- a/sdk/docs/pages/zksend/link-builder.mdx
+++ /dev/null
@@ -1,210 +0,0 @@
-import { Callout } from 'nextra/components';
-
-# Creating zkSend Links
-
-
- Products and services that incorporate zkSend links may be subject to financial regulations,
- including obtaining money transmitter licenses in jurisdictions where you provide your services.
- It is the developer's responsibility to ensure compliance with all relevant laws and obtain any
- necessary licenses. The information provided by Mysten Labs is not legal advice, and developers
- should consult with a qualified legal professional to address their specific circumstances.
-
-
-## Limitations
-
-- zkSend only supports mainnet at this time.
-- Objects within links must be publicly transferrable.
-
-## Create a link
-
-You can start creating your own zkSend link using the `ZkSendLinkBuilder` class. This class
-constructor takes an object with the following options:
-
-- **`sender`** (required) - Required. The address of the sender / creator of the link.
-- **`redirect`** (optional) - The redirect configuration for the link. See "Claim redirect" below
- for more information.
- - **`url`** - The url to redirect to after the link have been claimed.
- - **`name`** - The name of your dApp. This will be shown to the user when claiming the link.
-- **`client`** (optional) - The `@iota/iota.js` client used to fetch data to construct the link.
- If not provided, a default client will be used.
-
-```ts
-import { ZkSendLinkBuilder } from '@iota/zksend';
-
-const link = new ZkSendLinkBuilder({
- sender: '0x...',
-});
-```
-
-#### Adding IOTA to the link
-
-You can add IOTA to the link by calling `link.addClaimableMicros()`. This method takes the following
-params:
-
-- **`amount`** (required) - The amount of MICROS (the base unit of IOTA) to add to the link.
-
-#### Adding non-IOTA coins to the link
-
-You can add non-IOTA coins to the link by calling `link.addClaimableBalance()`. This method takes the
-following params:
-
-- **`coinType`** (required) - The coin type of the coin to add to the link (e.g. `0x2::iota::IOTA`).
-- **`amount`** (required) - The amount of the coin to add to the link. Represented in the base
- unit of the coin.
-
-The SDK will automatically perform the necessary coin management logic to transfer the defined
-amount, such as merging and splitting coin objects.
-
-#### Adding objects to the link
-
-You can add a publicly-transferrable object to the link by calling `link.addClaimableObject()`. This
-method takes the following params:
-
-- **`id`** (required) - The ID of the object. This must be owned by the `sender` you configured
- when creating the link.
-
-#### Getting the link URL
-
-At any time, you can get the URL for the link by calling `link.getLink()`.
-
-## Submitting the link transaction
-
-Once you have built your zkSend link, you need to execute a transaction to transfer assets and make
-the link claimable.
-
-You can call the `link.createSendTransaction()` method, which returns a `TransactionBlock` object
-that you can sign and submit to the blockchain.
-
-```ts
-const txb = await link.createSendTransaction();
-
-const { bytes, signature } = txb.sign({ client, signer: keypair });
-
-const result = await client.executeTransactionBlock({
- transactionBlock: bytes,
- signature,
-});
-```
-
-If you have a keypair you would like to send the transaction with, you can use the `create` method
-as shorthand for creating the send transaction, signing it, and submitting it to the blockchain.
-
-```ts
-await link.create({
- signer: yourKeypair,
-});
-```
-
-## Claim redirect
-
-You can configure a redirect for the link, which will redirect the user to a URL of your choice
-after the link has been claimed. This is useful for dApps that want to use zkSend as an onboarding
-tool, and have the user redirected to their dApp after claiming the link.
-
-To configure a redirect, you need to provide a `redirect` object when creating the link. This object
-takes the following params:
-
-- **`url`** - The URL to redirect to after the link has been claimed.
-- **`name`** - The name of your dApp. This will be shown to the user when claiming the link.
-
-When redirecting to the URL, if the user claims with zkLogin, then zkSend will automatically add a
-`zksend_address` query parameter to the URL, containing the Iota address of the user that claimed the
-asset. The [zkSend wallet](./dapp.mdx) will automatically read this query parameter, and consider
-itself connected as a result of a claim redirect.
-
-```ts
-import { ZkSendLinkBuilder } from '@iota/zksend';
-
-const link = new ZkSendLinkBuilder({
- sender: '0x...',
- redirect: {
- url: 'https://your-dapp.com',
- name: 'Your dApp',
- },
-});
-```
-
-## Claiming a link
-
-To claim a link via the SDK you can use the `ZkSendLink` class:
-
-```ts
-import { ZkSendLink } from '@iota/zksend';
-
-// create a link instance from a URL
-const link = await ZkSendLink.fromUrl('https://zksend.com/claim#$abc...');
-
-// list what claimable assets the link has
-const { nfts, balances } = link.assets;
-
-// claim all the assets from the link
-await link.claimAssets(addressOfClaimer);
-```
-
-## Listing links you have created
-
-To list the links created by a specific address, you can use the `listCreatedLinks` function:
-
-```ts
-import { listCreatedLinks } from '@iota/zksend';
-
-const { links, hasNextPage, cursor } = await listCreatedLinks({
- address: addressOfCreator,
-});
-
-// get the claimable assets for this link (will be empty if the link has been claimed)
-const { nfts, balances } = await links[0].assets;
-```
-
-## Regenerating links
-
-If you lose a link you've created, you can re-generate the link (this can only done from the address
-that originally created the link):
-
-```ts
-import { listCreatedLinks } from '@iota/zksend';
-
-const { links, hasNextPage, cursor } = await listCreatedLinks({
- address: addressOfCreator,
-});
-
-// url will be the new link url
-const { url, transactionBlock } = await links[0].link.createRegenerateTransaction(
- addressOfLinkCreator,
-);
-
-// Execute the transaction block to regenerate the link
-await client.signAndExecuteTransactionBlock({
- transactionBlock,
- signer: keypair,
-});
-```
-
-## Bulk link creation
-
-To create multiple links in a single transaction block, you can use `ZkSendLinkBuilder.createLinks`:
-
-```ts
-const links = [];
-
-for (let i = 0; i < 10; i++) {
- const link = new ZkSendLinkBuilder({
- client,
- sender: keypair.toIotaAddress(),
- });
-
- link.addClaimableMicros(100n);
- links.push(link);
-}
-
-const urls = links.map((link) => link.getLink());
-
-const txb = await ZkSendLinkBuilder.createLinks({
- links,
-});
-
-await client.signAndExecuteTransactionBlock({
- transactionBlock: txb,
- signer: keypair,
-});
-```
diff --git a/sdk/docs/typedoc.json b/sdk/docs/typedoc.json
index 044c6ad4f1c..d444630da81 100644
--- a/sdk/docs/typedoc.json
+++ b/sdk/docs/typedoc.json
@@ -7,8 +7,7 @@
"../graphql-transport",
"../kiosk",
"../typescript",
- "../zklogin",
- "../zksend"
+ "../zklogin"
],
"excludeInternal": true,
"excludePrivate": true,
diff --git a/sdk/zksend/.prettierignore b/sdk/zksend/.prettierignore
deleted file mode 100644
index f44447b8ce9..00000000000
--- a/sdk/zksend/.prettierignore
+++ /dev/null
@@ -1,2 +0,0 @@
-CHANGELOG.md
-dist/
diff --git a/sdk/zksend/CHANGELOG.md b/sdk/zksend/CHANGELOG.md
deleted file mode 100644
index e7a4752dccf..00000000000
--- a/sdk/zksend/CHANGELOG.md
+++ /dev/null
@@ -1,125 +0,0 @@
-# @iota/zksend
-
-## 0.4.1
-
-### Patch Changes
-
-- Updated dependencies [6984dd1e38]
- - @iota/iota.js@0.51.1
- - @iota/wallet-standard@0.11.1
-
-## 0.4.0
-
-### Minor Changes
-
-- c05a4e8cb7: removed listClaimableAssets, and added new assets and claimed properties to link instances
-- c05a4e8cb7: Use contract by default for new links
-- c05a4e8cb7: Add helper for bulk link creation
-- c05a4e8cb7: Removed options for filtering claims
-- c05a4e8cb7: renamed loadOwnedData to loadAssets
-
-## 0.3.1
-
-### Patch Changes
-
-- b82832279b: Add isClaimTransaction helper
-
-## 0.3.0
-
-### Minor Changes
-
-- 3b1da3967a: Add support for contract based links
-
-## 0.2.3
-
-### Patch Changes
-
-- Updated dependencies [0cafa94027]
-- Updated dependencies [437f0ca2ef]
- - @iota/iota.js@0.51.0
- - @iota/wallet-standard@0.11.0
-
-## 0.2.2
-
-### Patch Changes
-
-- 4830361fa4: Updated typescript version
-- 4fd676671b: Fix issue with overwriting balances when adding multiple balances for the same unnormalized coinType"
-- Updated dependencies [4830361fa4]
- - @iota/wallet-standard@0.10.3
- - @iota/iota.js@0.50.1
-
-## 0.2.1
-
-### Patch Changes
-
-- f069e3a13d: fix listing assets for empty links
-
-## 0.2.0
-
-### Minor Changes
-
-- e81f49e8dc: Add SDK for creating ZKSend links
-
-### Patch Changes
-
-- c07aa19958: Fix coin merging for sending balances
-- 13e922d9b1: Rework timing and window opening logic to try and improve browser compatibility
-- c859f41a1c: Handle base64 with spaces in hash
-- d21c01ed47: Add method for claiming zksend assets from link
-- 2814db6529: Fix required redirect
-- e87d99734a: Add method for sending non-iota balances
-- ba6fccd010: Add support for autoconnection from redirects
-- c6b3066069: Fix cursor when enumerating links owned assets
-- 66fbbc7faa: Detect gasCoin when claiming
-- 7b8d044603: Detect wallet closing
-- c6b3066069: Improve zkSend error messages
-- a2904e0075: Fix for claimable assets not accounting for cases where claimable balance comes from gas coin
-- ea2744b0c3: Add redirect parameter and fix listing assets on links without Iota
-- 44a1f9ea0b: Tweak types of events sent over the bridge
-- 7cc09a7bb4: Handle cases where list of objects to transfer is empty
-- 9a14e61db4: Add gas estimation for creating zksend links
-- f041b10b9f: Allow origin to be set when registering zksend wallet"
-- c1f6cfff47: Fix import paths
-- 7c9a8cc24b: Fix window opening for transactions with unresolved data
-- ae9ae17eea: Fix ownedAfterClaim check
-- Updated dependencies [a34f1cb67d]
-- Updated dependencies [c08e3569ef]
-- Updated dependencies [9a14e61db4]
-- Updated dependencies [13e922d9b1]
-- Updated dependencies [a34f1cb67d]
-- Updated dependencies [220a766d86]
- - @iota/iota.js@0.50.0
- - @iota/wallet-standard@0.10.2
-
-## 0.1.1
-
-### Patch Changes
-
-- Updated dependencies [9ac0a4ec01]
- - @iota/wallet-standard@0.10.1
-
-## 0.1.0
-
-### Minor Changes
-
-- e5f9e3ba21: Replace tsup based build to fix issues with esm/cjs dual publishing
-
-### Patch Changes
-
-- Updated dependencies [e5f9e3ba21]
- - @iota/wallet-standard@0.10.0
-
-## 0.0.3
-
-### Patch Changes
-
-- Updated dependencies [dd362ec1d6]
-- Updated dependencies [165ad6b21d]
- - @iota/wallet-standard@0.9.0
-
-## 0.0.2
-
-### Patch Changes
-
-- @iota/wallet-standard@0.8.11
diff --git a/sdk/zksend/README.md b/sdk/zksend/README.md
deleted file mode 100644
index bcc4d938265..00000000000
--- a/sdk/zksend/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# `@iota/zksend`
diff --git a/sdk/zksend/package.json b/sdk/zksend/package.json
deleted file mode 100644
index 52d6e4aa22d..00000000000
--- a/sdk/zksend/package.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "name": "@iota/zksend",
- "version": "0.4.1",
- "description": "TODO: Write Description",
- "license": "Apache-2.0",
- "author": "Mysten Labs ",
- "type": "commonjs",
- "main": "./dist/cjs/index.js",
- "module": "./dist/esm/index.js",
- "types": "./dist/cjs/index.d.ts",
- "exports": {
- ".": {
- "import": "./dist/esm/index.js",
- "require": "./dist/cjs/index.js"
- }
- },
- "sideEffects": false,
- "files": [
- "CHANGELOG.md",
- "dist"
- ],
- "scripts": {
- "clean": "rm -rf tsconfig.tsbuildinfo ./dist",
- "build": "build-package",
- "prepublishOnly": "pnpm build",
- "prettier:check": "prettier -c --ignore-unknown .",
- "prettier:fix": "prettier -w --ignore-unknown .",
- "eslint:check": "eslint --max-warnings=0 .",
- "eslint:fix": "pnpm run eslint:check --fix",
- "lint": "pnpm run eslint:check && pnpm run prettier:check",
- "lint:fix": "pnpm run eslint:fix && pnpm run prettier:fix"
- },
- "repository": {
- "type": "git",
- "url": "git+https://github.com/iotaledger/iota.git"
- },
- "bugs": {
- "url": "https://github.com/iotaledger/iota/issues"
- },
- "homepage": "https://github.com/iotaledger/iota#readme",
- "devDependencies": {
- "@iota/build-scripts": "workspace:*",
- "@types/node": "^20.4.2",
- "typescript": "^5.3.3",
- "vitest": "^0.33.0"
- },
- "dependencies": {
- "@iota/iota.js": "workspace:*",
- "@iota/wallet-standard": "workspace:*",
- "mitt": "^3.0.1",
- "nanostores": "^0.9.3",
- "valibot": "^0.25.0"
- }
-}
diff --git a/sdk/zksend/src/channel/events.ts b/sdk/zksend/src/channel/events.ts
deleted file mode 100644
index 9cc1c69c2e9..00000000000
--- a/sdk/zksend/src/channel/events.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import type { Output } from 'valibot';
-import { literal, object, optional, string, url, uuid, variant } from 'valibot';
-
-export const ZkSendRequestData = variant('type', [
- object({
- type: literal('connect'),
- }),
- object({
- type: literal('sign-transaction-block'),
- data: string('`data` is required'),
- address: string('`address` is required'),
- }),
- object({
- type: literal('sign-personal-message'),
- bytes: string('`bytes` is required'),
- address: string('`address` is required'),
- }),
-]);
-export type ZkSendRequestData = Output;
-
-export const ZkSendRequest = object({
- id: string('`id` is required', [uuid()]),
- origin: string([url('`origin` must be a valid URL')]),
- name: optional(string()),
- payload: ZkSendRequestData,
-});
-
-export type ZkSendRequest = Output;
-
-export const ZkSendResponseData = variant('type', [
- object({
- type: literal('connect'),
- address: string(),
- }),
- object({
- type: literal('sign-transaction-block'),
- bytes: string(),
- signature: string(),
- }),
- object({
- type: literal('sign-personal-message'),
- bytes: string(),
- signature: string(),
- }),
-]);
-export type ZkSendResponseData = Output;
-
-export const ZkSendResponsePayload = variant('type', [
- object({
- type: literal('reject'),
- }),
- object({
- type: literal('resolve'),
- data: ZkSendResponseData,
- }),
-]);
-export type ZkSendResponsePayload = Output;
-
-export const ZkSendResponse = object({
- id: string([uuid()]),
- source: literal('zksend-channel'),
- payload: ZkSendResponsePayload,
-});
-export type ZkSendResponse = Output;
-
-export type ZkSendRequestTypes = Record & {
- [P in ZkSendRequestData as P['type']]: P;
-};
-
-export type ZkSendResponseTypes = {
- [P in ZkSendResponseData as P['type']]: P;
-};
diff --git a/sdk/zksend/src/channel/index.ts b/sdk/zksend/src/channel/index.ts
deleted file mode 100644
index 31bedaecd50..00000000000
--- a/sdk/zksend/src/channel/index.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import type { Output } from 'valibot';
-import { parse, safeParse } from 'valibot';
-
-import { withResolvers } from '../utils/withResolvers.js';
-import type { ZkSendRequestData, ZkSendResponsePayload, ZkSendResponseTypes } from './events.js';
-import { ZkSendRequest, ZkSendResponse } from './events.js';
-
-export const DEFAULT_ZKSEND_ORIGIN = 'https://zksend.com';
-
-export { ZkSendRequest, ZkSendResponse };
-
-interface ZkSendPopupOptions {
- origin?: string;
- name: string;
-}
-
-export class ZkSendPopup {
- #id: string;
- #origin: string;
- #name: string;
-
- #close?: () => void;
-
- constructor({ origin = DEFAULT_ZKSEND_ORIGIN, name }: ZkSendPopupOptions) {
- this.#id = crypto.randomUUID();
- this.#origin = origin;
- this.#name = name;
- }
-
- async createRequest(
- request: T,
- ): Promise {
- const popup = window.open('about:blank', '_blank');
-
- if (!popup) {
- throw new Error('Failed to open new window');
- }
-
- const { promise, resolve, reject } = withResolvers();
-
- let interval: NodeJS.Timer | null = null;
-
- function cleanup() {
- if (interval) {
- clearInterval(interval);
- }
- window.removeEventListener('message', listener);
- }
-
- const listener = (event: MessageEvent) => {
- if (event.origin !== this.#origin) {
- return;
- }
- const { success, output } = safeParse(ZkSendResponse, event.data);
- if (!success || output.id !== this.#id) return;
-
- cleanup();
-
- if (output.payload.type === 'reject') {
- reject(new Error('User rejected the request'));
- } else if (output.payload.type === 'resolve') {
- resolve(output.payload.data as ZkSendResponseTypes[T['type']]);
- }
- };
-
- this.#close = () => {
- cleanup();
- popup?.close();
- };
-
- window.addEventListener('message', listener);
-
- const { type, ...data } = request;
-
- popup?.location.assign(
- `${this.#origin}/dapp/${type}?${new URLSearchParams({
- id: this.#id,
- origin: window.origin,
- name: this.#name,
- })}${data ? `#${new URLSearchParams(data as Record)}` : ''}`,
- );
-
- interval = setInterval(() => {
- try {
- if (popup?.closed) {
- cleanup();
- reject(new Error('User closed the zkSend window'));
- }
- } catch {
- // This can error during the login flow, but that's fine.
- }
- }, 1000);
-
- return promise;
- }
-
- close() {
- this.#close?.();
- }
-}
-
-export class ZkSendHost {
- #request: Output;
-
- constructor(request: Output) {
- if (typeof window === 'undefined' || !window.opener) {
- throw new Error(
- 'ZkSendHost can only be used in a window opened through `window.open`. `window.opener` is not available.',
- );
- }
-
- this.#request = request;
- }
-
- static fromUrl(url: string = window.location.href) {
- const parsed = new URL(url);
-
- const urlHashData = parsed.hash
- ? Object.fromEntries(
- [...new URLSearchParams(parsed.hash.slice(1))].map(([key, value]) => [
- key,
- value.replace(/ /g, '+'),
- ]),
- )
- : {};
-
- const request = parse(ZkSendRequest, {
- id: parsed.searchParams.get('id'),
- origin: parsed.searchParams.get('origin'),
- name: parsed.searchParams.get('name'),
- payload: {
- type: parsed.pathname.split('/').pop(),
- ...urlHashData,
- },
- });
-
- return new ZkSendHost(request);
- }
-
- getRequestData() {
- return this.#request;
- }
-
- sendMessage(payload: ZkSendResponsePayload) {
- window.opener.postMessage(
- {
- id: this.#request.id,
- source: 'zksend-channel',
- payload,
- } satisfies ZkSendResponse,
- this.#request.origin,
- );
- }
-
- close(payload?: ZkSendResponsePayload) {
- if (payload) {
- this.sendMessage(payload);
- }
- window.close();
- }
-}
diff --git a/sdk/zksend/src/index.test.ts b/sdk/zksend/src/index.test.ts
deleted file mode 100644
index 0b5a2b64e74..00000000000
--- a/sdk/zksend/src/index.test.ts
+++ /dev/null
@@ -1,483 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { getFullnodeUrl, IotaClient, IotaObjectChange } from '@iota/iota.js/client';
-import { decodeIotaPrivateKey } from '@iota/iota.js/cryptography';
-// import { getFaucetHost, requestIotaFromFaucetV0 } from '@iota/iota.js/faucet';
-import { Ed25519Keypair } from '@iota/iota.js/keypairs/ed25519';
-import { TransactionBlock } from '@iota/iota.js/transactions';
-import { toB64 } from '@iota/iota.js/utils';
-import { describe } from 'node:test';
-import { expect, test } from 'vitest';
-
-import { ZkSendLink, ZkSendLinkBuilder } from './index.js';
-import { listCreatedLinks } from './links/list-created-links.js';
-
-export const DEMO_BEAR_CONFIG = {
- packageId: '0xab8ed19f16874f9b8b66b0b6e325ee064848b1a7fdcb1c2f0478b17ad8574e65',
- type: '0xab8ed19f16874f9b8b66b0b6e325ee064848b1a7fdcb1c2f0478b17ad8574e65::demo_bear::DemoBear',
-};
-
-export const ZK_BAG_CONFIG = {
- packageId: '0x036fee67274d0d85c3532f58296abe0dee86b93864f1b2b9074be6adb388f138',
- bagStoreId: '0x5c63e71734c82c48a3cb9124c54001d1a09736cfb1668b3b30cd92a96dd4d0ce',
- bagStoreTableId: '0x4e1bc4085d64005e03eb4eab2510d527aeba9548cda431cb8f149ff37451f870',
-};
-
-const client = new IotaClient({
- url: getFullnodeUrl('testnet'),
-});
-
-// 0x6e43d0e58341db532a87a16aaa079ae6eb1ed3ae8b77fdfa4870a268ea5d5db8
-const keypair = Ed25519Keypair.fromSecretKey(
- decodeIotaPrivateKey('iotaprivkey1qrlgsqryjmmt59nw7a76myeeadxrs3esp8ap2074qz8xaq5kens32f7e3u7')
- .secretKey,
-);
-
-// Automatically get gas from testnet is not working reliably, manually request gas via discord,
-// or uncomment the beforeAll and gas function below
-// beforeAll(async () => {
-// await getIotaFromFaucet(keypair);
-// });
-
-// async function getIotaFromFaucet(keypair: Keypair) {
-// const faucetHost = getFaucetHost('testnet');
-// const result = await requestIotaFromFaucetV0({
-// host: faucetHost,
-// recipient: keypair.toIotaAddress(),
-// });
-
-// if (result.error) {
-// throw new Error(result.error);
-// }
-// }
-
-describe('Contract links', () => {
- test(
- 'create and claim link',
- async () => {
- const link = new ZkSendLinkBuilder({
- client,
- contract: ZK_BAG_CONFIG,
- sender: keypair.toIotaAddress(),
- });
-
- const bears = await createBears(3);
-
- for (const bear of bears) {
- link.addClaimableObject(bear.objectId);
- }
-
- link.addClaimableMicros(100n);
-
- const linkUrl = link.getLink();
-
- await link.create({
- signer: keypair,
- waitForTransactionBlock: true,
- });
-
- const claimLink = await ZkSendLink.fromUrl(linkUrl, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- });
-
- const claimableAssets = claimLink.assets!;
-
- expect(claimLink.claimed).toEqual(false);
- expect(claimableAssets.nfts.length).toEqual(3);
- expect(claimableAssets.balances).toMatchInlineSnapshot(`
- [
- {
- "amount": 100n,
- "coinType": "0x0000000000000000000000000000000000000000000000000000000000000002::iota::IOTA",
- },
- ]
- `);
-
- const claim = await claimLink.claimAssets(keypair.toIotaAddress());
-
- const res = await client.waitForTransactionBlock({
- digest: claim.digest,
- options: {
- showObjectChanges: true,
- },
- });
-
- expect(res.objectChanges?.length).toEqual(
- 3 + // bears,
- 1 + // coin
- 1 + // gas
- 1, // bag
- );
-
- const link2 = await ZkSendLink.fromUrl(linkUrl, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- });
- expect(link2.assets?.balances).toEqual(claimLink.assets?.balances);
- expect(link2.assets?.nfts.map((nft) => nft.objectId)).toEqual(
- claimLink.assets?.nfts.map((nft) => nft.objectId),
- );
- expect(link2.claimed).toEqual(true);
- },
- {
- timeout: 30_000,
- },
- );
-
- test(
- 'regenerate links',
- async () => {
- const linkKp = new Ed25519Keypair();
- const link = new ZkSendLinkBuilder({
- keypair: linkKp,
- client,
- contract: ZK_BAG_CONFIG,
- sender: keypair.toIotaAddress(),
- });
-
- const bears = await createBears(3);
-
- for (const bear of bears) {
- link.addClaimableObject(bear.objectId);
- }
-
- link.addClaimableMicros(100n);
-
- await link.create({
- signer: keypair,
- waitForTransactionBlock: true,
- });
-
- const {
- links: [lostLink],
- } = await listCreatedLinks({
- address: keypair.toIotaAddress(),
- network: 'testnet',
- contract: ZK_BAG_CONFIG,
- });
-
- const { url, transactionBlock } = await lostLink.link.createRegenerateTransaction(
- keypair.toIotaAddress(),
- );
-
- const result = await client.signAndExecuteTransactionBlock({
- transactionBlock,
- signer: keypair,
- options: {
- showEffects: true,
- showObjectChanges: true,
- },
- });
-
- await client.waitForTransactionBlock({ digest: result.digest });
-
- const claimLink = await ZkSendLink.fromUrl(url, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- });
-
- expect(claimLink.assets?.nfts.length).toEqual(3);
- expect(claimLink.assets?.balances).toMatchInlineSnapshot(`
- [
- {
- "amount": 100n,
- "coinType": "0x0000000000000000000000000000000000000000000000000000000000000002::iota::IOTA",
- },
- ]
- `);
-
- const claim = await claimLink.claimAssets(keypair.toIotaAddress());
-
- const res = await client.waitForTransactionBlock({
- digest: claim.digest,
- options: {
- showObjectChanges: true,
- },
- });
-
- expect(res.objectChanges?.length).toEqual(
- 3 + // bears,
- 1 + // coin
- 1 + // gas
- 1, // bag
- );
- const link2 = await ZkSendLink.fromUrl(url, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- });
- expect(link2.assets?.balances).toEqual(claimLink.assets?.balances);
- expect(link2.assets?.nfts.map((nft) => nft.objectId)).toEqual(
- claimLink.assets?.nfts.map((nft) => nft.objectId),
- );
- expect(link2.claimed).toEqual(true);
- },
- {
- timeout: 30_000,
- },
- );
-
- test(
- 'bulk link creation',
- async () => {
- const bears = await createBears(3);
-
- const links = [];
- for (const bear of bears) {
- const link = new ZkSendLinkBuilder({
- client,
- contract: ZK_BAG_CONFIG,
- sender: keypair.toIotaAddress(),
- });
-
- link.addClaimableMicros(100n);
- link.addClaimableObject(bear.objectId);
-
- links.push(link);
- }
-
- const txb = await ZkSendLinkBuilder.createLinks({
- links,
- client,
- contract: ZK_BAG_CONFIG,
- });
-
- const result = await client.signAndExecuteTransactionBlock({
- transactionBlock: txb,
- signer: keypair,
- });
-
- await client.waitForTransactionBlock({ digest: result.digest });
-
- for (const link of links) {
- const linkUrl = link.getLink();
-
- const claimLink = await ZkSendLink.fromUrl(linkUrl, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- });
-
- const claimableAssets = claimLink.assets!;
-
- expect(claimLink.claimed).toEqual(false);
- expect(claimableAssets.nfts.length).toEqual(1);
- expect(claimableAssets.balances).toMatchInlineSnapshot(`
- [
- {
- "amount": 100n,
- "coinType": "0x0000000000000000000000000000000000000000000000000000000000000002::iota::IOTA",
- },
- ]
- `);
-
- const claim = await claimLink.claimAssets(keypair.toIotaAddress());
-
- const res = await client.waitForTransactionBlock({
- digest: claim.digest,
- options: {
- showObjectChanges: true,
- },
- });
-
- expect(res.objectChanges?.length).toEqual(
- 1 + // bears,
- 1 + // coin
- 1 + // gas
- 1, // bag
- );
- }
- },
- {
- timeout: 60_000,
- },
- );
-});
-
-describe('Non contract links', () => {
- test(
- 'Links with separate gas coin',
- async () => {
- const link = new ZkSendLinkBuilder({
- client,
- sender: keypair.toIotaAddress(),
- contract: null,
- });
-
- const bears = await createBears(3);
-
- for (const bear of bears) {
- link.addClaimableObject(bear.objectId);
- }
-
- link.addClaimableMicros(100n);
-
- const linkUrl = link.getLink();
-
- await link.create({
- signer: keypair,
- waitForTransactionBlock: true,
- });
-
- // Balances sometimes not updated even though we wait for the transaction to be indexed
- await new Promise((resolve) => setTimeout(resolve, 3000));
-
- const claimLink = await ZkSendLink.fromUrl(linkUrl, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- });
-
- expect(claimLink.assets?.nfts.length).toEqual(3);
- expect(claimLink.assets?.balances).toMatchInlineSnapshot(`
- [
- {
- "amount": 100n,
- "coinType": "0x0000000000000000000000000000000000000000000000000000000000000002::iota::IOTA",
- },
- ]
- `);
-
- const claimTx = await claimLink.claimAssets(new Ed25519Keypair().toIotaAddress());
-
- const res = await client.waitForTransactionBlock({
- digest: claimTx.digest,
- options: {
- showObjectChanges: true,
- },
- });
-
- expect(res.objectChanges?.length).toEqual(
- 3 + // bears,
- 1 + // coin
- 1, // gas
- );
-
- const link2 = await ZkSendLink.fromUrl(linkUrl, {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- });
- expect(link2.assets?.balances).toEqual(claimLink.assets?.balances);
- expect(link2.assets?.nfts.map((nft) => nft.objectId)).toEqual(
- claimLink.assets?.nfts.map((nft) => nft.objectId),
- );
- expect(link2.claimed).toEqual(true);
- },
- {
- timeout: 30_000,
- },
- );
-
- test(
- 'Links with single coin',
- async () => {
- const linkKp = new Ed25519Keypair();
-
- const txb = new TransactionBlock();
-
- const [coin] = txb.splitCoins(txb.gas, [5_000_000]);
- txb.transferObjects([coin], linkKp.toIotaAddress());
-
- const { digest } = await client.signAndExecuteTransactionBlock({
- signer: keypair,
- transactionBlock: txb,
- });
-
- await client.waitForTransactionBlock({ digest });
-
- const claimLink = new ZkSendLink({
- keypair: linkKp,
- network: 'testnet',
- isContractLink: false,
- });
-
- await claimLink.loadAssets();
-
- expect(claimLink.assets?.nfts.length).toEqual(0);
- expect(claimLink.assets?.balances.length).toEqual(1);
- expect(claimLink.assets?.balances[0].coinType).toEqual(
- '0x0000000000000000000000000000000000000000000000000000000000000002::iota::IOTA',
- );
-
- const claimTx = await claimLink.claimAssets(keypair.toIotaAddress());
-
- const res = await client.waitForTransactionBlock({
- digest: claimTx.digest,
- options: {
- showBalanceChanges: true,
- },
- });
-
- expect(res.balanceChanges?.length).toEqual(2);
- const link2 = await ZkSendLink.fromUrl(
- `https://zksend.con/claim#${toB64(
- decodeIotaPrivateKey(linkKp.getSecretKey()).secretKey,
- )}`,
- {
- contract: ZK_BAG_CONFIG,
- network: 'testnet',
- claimApi: 'https://zksend-git-mh-contract-claims-mysten-labs.vercel.app/api',
- },
- );
- expect(link2.assets?.balances).toEqual(claimLink.assets?.balances);
- expect(link2.assets?.nfts.map((nft) => nft.objectId)).toEqual(
- claimLink.assets?.nfts.map((nft) => nft.objectId),
- );
- expect(link2.claimed).toEqual(true);
- },
- {
- timeout: 30_000,
- },
- );
-});
-
-async function createBears(totalBears: number) {
- const txb = new TransactionBlock();
- const bears = [];
-
- for (let i = 0; i < totalBears; i++) {
- const bear = txb.moveCall({
- target: `${DEMO_BEAR_CONFIG.packageId}::demo_bear::new`,
- arguments: [
- txb.pure.string(`A happy bear - ${Math.floor(Math.random() * 1_000_000_000)}`),
- ],
- });
-
- bears.push(bear);
- }
-
- txb.transferObjects(bears, txb.pure.address(keypair.toIotaAddress()));
-
- const res = await client.signAndExecuteTransactionBlock({
- transactionBlock: txb,
- signer: keypair,
- options: {
- showObjectChanges: true,
- },
- });
-
- await client.waitForTransactionBlock({
- digest: res.digest,
- });
-
- const bearList = res
- .objectChanges!.filter(
- (x: IotaObjectChange) =>
- x.type === 'created' && x.objectType.includes(DEMO_BEAR_CONFIG.type),
- )
- .map((x: IotaObjectChange) => {
- if (!('objectId' in x)) throw new Error('invalid data');
- return {
- objectId: x.objectId,
- type: x.objectType,
- };
- });
-
- return bearList;
-}
diff --git a/sdk/zksend/src/index.ts b/sdk/zksend/src/index.ts
deleted file mode 100644
index 59940531747..00000000000
--- a/sdk/zksend/src/index.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-export {
- ZkSendLinkBuilder,
- type ZkSendLinkBuilderOptions,
- type CreateZkSendLinkOptions,
-} from './links/builder.js';
-export { ZkSendLink, type ZkSendLinkOptions } from './links/claim.js';
-export { type ZkBagContractOptions, ZkBag } from './links/zk-bag.js';
-export { isClaimTransaction } from './links/utils.js';
-export { listCreatedLinks } from './links/list-created-links.js';
-
-export { MAINNET_CONTRACT_IDS } from './links/zk-bag.js';
-export * from './wallet.js';
-export * from './channel/index.js';
diff --git a/sdk/zksend/src/links/builder.ts b/sdk/zksend/src/links/builder.ts
deleted file mode 100644
index 13152e2a12e..00000000000
--- a/sdk/zksend/src/links/builder.ts
+++ /dev/null
@@ -1,419 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { getFullnodeUrl, IotaClient } from '@iota/iota.js/client';
-import type { CoinStruct } from '@iota/iota.js/client';
-import { decodeIotaPrivateKey } from '@iota/iota.js/cryptography';
-import type { Keypair, Signer } from '@iota/iota.js/cryptography';
-import { Ed25519Keypair } from '@iota/iota.js/keypairs/ed25519';
-import type { TransactionObjectArgument, TransactionObjectInput } from '@iota/iota.js/transactions';
-import { TransactionBlock } from '@iota/iota.js/transactions';
-import {
- normalizeStructTag,
- normalizeIotaAddress,
- IOTA_TYPE_ARG,
- toB64,
-} from '@iota/iota.js/utils';
-
-import type { ZkBagContractOptions } from './zk-bag.js';
-import { MAINNET_CONTRACT_IDS, ZkBag } from './zk-bag.js';
-
-interface ZkSendLinkRedirect {
- url: string;
- name?: string;
-}
-
-export interface ZkSendLinkBuilderOptions {
- host?: string;
- path?: string;
- keypair?: Keypair;
- network?: 'mainnet' | 'testnet';
- client?: IotaClient;
- sender: string;
- redirect?: ZkSendLinkRedirect;
- contract?: ZkBagContractOptions | null;
-}
-
-const DEFAULT_ZK_SEND_LINK_OPTIONS = {
- host: 'https://zksend.com',
- path: '/claim',
- network: 'mainnet' as const,
-};
-
-const IOTA_COIN_TYPE = normalizeStructTag(IOTA_TYPE_ARG);
-
-export interface CreateZkSendLinkOptions {
- transactionBlock?: TransactionBlock;
- calculateGas?: (options: {
- balances: Map;
- objects: TransactionObjectInput[];
- gasEstimateFromDryRun: bigint;
- }) => Promise | bigint;
-}
-
-export class ZkSendLinkBuilder {
- objectIds = new Set();
- balances = new Map();
- sender: string;
- #host: string;
- #path: string;
- keypair: Keypair;
- #client: IotaClient;
- #redirect?: ZkSendLinkRedirect;
- #coinsByType = new Map();
- #contract?: ZkBag;
-
- constructor({
- host = DEFAULT_ZK_SEND_LINK_OPTIONS.host,
- path = DEFAULT_ZK_SEND_LINK_OPTIONS.path,
- keypair = new Ed25519Keypair(),
- network = DEFAULT_ZK_SEND_LINK_OPTIONS.network,
- client = new IotaClient({ url: getFullnodeUrl(network) }),
- sender,
- redirect,
- contract = network === 'mainnet' ? MAINNET_CONTRACT_IDS : undefined,
- }: ZkSendLinkBuilderOptions) {
- this.#host = host;
- this.#path = path;
- this.#redirect = redirect;
- this.keypair = keypair;
- this.#client = client;
- this.sender = normalizeIotaAddress(sender);
-
- if (contract) {
- this.#contract = new ZkBag(contract.packageId, contract);
- }
- }
-
- addClaimableMicros(amount: bigint) {
- this.addClaimableBalance(IOTA_COIN_TYPE, amount);
- }
-
- addClaimableBalance(coinType: string, amount: bigint) {
- const normalizedType = normalizeStructTag(coinType);
- this.balances.set(normalizedType, (this.balances.get(normalizedType) ?? 0n) + amount);
- }
-
- addClaimableObject(id: string) {
- this.objectIds.add(id);
- }
-
- getLink(): string {
- const link = new URL(this.#host);
- link.pathname = this.#path;
- link.hash = `${this.#contract ? '$' : ''}${toB64(
- decodeIotaPrivateKey(this.keypair.getSecretKey()).secretKey,
- )}`;
-
- if (this.#redirect) {
- link.searchParams.set('redirect_url', this.#redirect.url);
- if (this.#redirect.name) {
- link.searchParams.set('name', this.#redirect.name);
- }
- }
-
- return link.toString();
- }
-
- async create({
- signer,
- ...options
- }: CreateZkSendLinkOptions & {
- signer: Signer;
- waitForTransactionBlock?: boolean;
- }) {
- const txb = await this.createSendTransaction(options);
-
- const result = await this.#client.signAndExecuteTransactionBlock({
- transactionBlock: await txb.build({ client: this.#client }),
- signer,
- });
-
- if (options.waitForTransactionBlock) {
- await this.#client.waitForTransactionBlock({ digest: result.digest });
- }
-
- return result;
- }
- async createSendTransaction({
- transactionBlock = new TransactionBlock(),
- calculateGas,
- }: CreateZkSendLinkOptions = {}) {
- if (!this.#contract) {
- return this.#createSendTransactionWithoutContract({ transactionBlock, calculateGas });
- }
-
- transactionBlock.setSenderIfNotSet(this.sender);
-
- return ZkSendLinkBuilder.createLinks({
- transactionBlock,
- client: this.#client,
- contract: this.#contract.ids,
- links: [this],
- });
- }
-
- async #objectsToTransfer(txb: TransactionBlock) {
- const objectIDs = [...this.objectIds];
- const refsWithType: {
- ref: TransactionObjectArgument;
- type: string;
- }[] = (
- await this.#client.multiGetObjects({
- ids: objectIDs,
- options: {
- showType: true,
- },
- })
- ).map((res, i) => {
- if (!res.data || res.error) {
- throw new Error(`Failed to load object ${objectIDs[i]} (${res.error?.code})`);
- }
-
- return {
- ref: txb.objectRef({
- version: res.data.version,
- digest: res.data.digest,
- objectId: res.data.objectId,
- }),
- type: res.data.type!,
- };
- });
-
- txb.setSenderIfNotSet(this.sender);
-
- for (const [coinType, amount] of this.balances) {
- if (coinType === IOTA_COIN_TYPE) {
- const [iota] = txb.splitCoins(txb.gas, [amount]);
- refsWithType.push({
- ref: iota,
- type: `0x2::coin::Coin<${coinType}>`,
- } as never);
- } else {
- const coins = (await this.#getCoinsByType(coinType)).map(
- (coin) => coin.coinObjectId,
- );
-
- if (coins.length > 1) {
- txb.mergeCoins(coins[0], coins.slice(1));
- }
- const [split] = txb.splitCoins(coins[0], [amount]);
- refsWithType.push({
- ref: split,
- type: `0x2::coin:Coin<${coinType}>`,
- });
- }
- }
-
- return refsWithType;
- }
-
- async #createSendTransactionWithoutContract({
- transactionBlock: txb = new TransactionBlock(),
- calculateGas,
- }: CreateZkSendLinkOptions = {}) {
- const gasEstimateFromDryRun = await this.#estimateClaimGasFee();
- const baseGasAmount = calculateGas
- ? await calculateGas({
- balances: this.balances,
- objects: [...this.objectIds],
- gasEstimateFromDryRun,
- })
- : gasEstimateFromDryRun * 2n;
-
- // Ensure that rounded gas is not less than the calculated gas
- const gasWithBuffer = baseGasAmount + 1013n;
- // Ensure that gas amount ends in 987
- const roundedGasAmount = gasWithBuffer - (gasWithBuffer % 1000n) - 13n;
-
- const address = this.keypair.toIotaAddress();
- const objectsToTransfer = (await this.#objectsToTransfer(txb)).map((obj) => obj.ref);
- const [gas] = txb.splitCoins(txb.gas, [roundedGasAmount]);
- objectsToTransfer.push(gas);
-
- txb.setSenderIfNotSet(this.sender);
- txb.transferObjects(objectsToTransfer, address);
-
- return txb;
- }
-
- async #estimateClaimGasFee(): Promise {
- const txb = new TransactionBlock();
- txb.setSender(this.sender);
- txb.setGasPayment([]);
- txb.transferObjects([txb.gas], this.keypair.toIotaAddress());
-
- const idsToTransfer = [...this.objectIds];
-
- for (const [coinType] of this.balances) {
- const coins = await this.#getCoinsByType(coinType);
-
- if (!coins.length) {
- throw new Error(`Sending account does not contain any coins of type ${coinType}`);
- }
-
- idsToTransfer.push(coins[0].coinObjectId);
- }
-
- if (idsToTransfer.length > 0) {
- txb.transferObjects(
- idsToTransfer.map((id) => txb.object(id)),
- this.keypair.toIotaAddress(),
- );
- }
-
- const result = await this.#client.dryRunTransactionBlock({
- transactionBlock: await txb.build({ client: this.#client }),
- });
-
- return (
- BigInt(result.effects.gasUsed.computationCost) +
- BigInt(result.effects.gasUsed.storageCost) -
- BigInt(result.effects.gasUsed.storageRebate)
- );
- }
-
- async #getCoinsByType(coinType: string) {
- if (this.#coinsByType.has(coinType)) {
- return this.#coinsByType.get(coinType)!;
- }
-
- const coins = await this.#client.getCoins({
- coinType,
- owner: this.sender,
- });
-
- this.#coinsByType.set(coinType, coins.data);
-
- return coins.data;
- }
-
- static async createLinks({
- links,
- network = 'mainnet',
- client = new IotaClient({ url: getFullnodeUrl(network) }),
- transactionBlock = new TransactionBlock(),
- contract: contractIds = MAINNET_CONTRACT_IDS,
- }: {
- transactionBlock?: TransactionBlock;
- client?: IotaClient;
- network?: 'mainnet' | 'testnet';
- links: ZkSendLinkBuilder[];
- contract: ZkBagContractOptions;
- }) {
- const contract = new ZkBag(contractIds.packageId, contractIds);
- const store = transactionBlock.object(contract.ids.bagStoreId);
-
- const coinsByType = new Map();
- const allIds = links.flatMap((link) => [...link.objectIds]);
-
- await Promise.all(
- [...new Set(links.flatMap((link) => [...link.balances.keys()]))].map(
- async (coinType) => {
- const coins = await client.getCoins({
- coinType,
- owner: links[0].sender,
- });
-
- coinsByType.set(
- coinType,
- coins.data.filter((coin) => !allIds.includes(coin.coinObjectId)),
- );
- },
- ),
- );
-
- const objectRefs = new Map<
- string,
- {
- ref: TransactionObjectArgument;
- type: string;
- }
- >();
-
- const pageSize = 50;
- let offset = 0;
- while (offset < allIds.length) {
- const chunk = allIds.slice(offset, offset + pageSize);
- offset += pageSize;
-
- const objects = await client.multiGetObjects({
- ids: chunk,
- options: {
- showType: true,
- },
- });
-
- for (const [i, res] of objects.entries()) {
- if (!res.data || res.error) {
- throw new Error(`Failed to load object ${chunk[i]} (${res.error?.code})`);
- }
- objectRefs.set(chunk[i], {
- ref: transactionBlock.objectRef({
- version: res.data.version,
- digest: res.data.digest,
- objectId: res.data.objectId,
- }),
- type: res.data.type!,
- });
- }
- }
-
- const mergedCoins = new Map([
- [IOTA_COIN_TYPE, transactionBlock.gas],
- ]);
-
- for (const [coinType, coins] of coinsByType) {
- if (coinType === IOTA_COIN_TYPE) {
- continue;
- }
-
- const [first, ...rest] = coins.map((coin) =>
- transactionBlock.objectRef({
- objectId: coin.coinObjectId,
- version: coin.version,
- digest: coin.digest,
- }),
- );
- if (rest.length > 0) {
- transactionBlock.mergeCoins(first, rest);
- }
- mergedCoins.set(coinType, transactionBlock.object(first));
- }
-
- for (const link of links) {
- const receiver = link.keypair.toIotaAddress();
- contract.new(transactionBlock, { arguments: [store, receiver] });
-
- link.objectIds.forEach((id) => {
- const object = objectRefs.get(id);
- if (!object) {
- throw new Error(`Object ${id} not found`);
- }
- contract.add(transactionBlock, {
- arguments: [store, receiver, object.ref],
- typeArguments: [object.type],
- });
- });
- }
-
- for (const [coinType, merged] of mergedCoins) {
- const linksWithCoin = links.filter((link) => link.balances.has(coinType));
- if (linksWithCoin.length === 0) {
- continue;
- }
-
- const balances = linksWithCoin.map((link) => link.balances.get(coinType)!);
- const splits = transactionBlock.splitCoins(merged, balances);
- for (const [i, link] of linksWithCoin.entries()) {
- contract.add(transactionBlock, {
- arguments: [store, link.keypair.toIotaAddress(), splits[i]],
- typeArguments: [`0x2::coin::Coin<${coinType}>`],
- });
- }
- }
-
- return transactionBlock;
- }
-}
diff --git a/sdk/zksend/src/links/claim.ts b/sdk/zksend/src/links/claim.ts
deleted file mode 100644
index a3c4a007608..00000000000
--- a/sdk/zksend/src/links/claim.ts
+++ /dev/null
@@ -1,691 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import type { PureArg } from '@iota/iota.js/bcs';
-import { bcs } from '@iota/iota.js/bcs';
-import { getFullnodeUrl, IotaClient } from '@iota/iota.js/client';
-import type { CoinStruct, IotaTransaction } from '@iota/iota.js/client';
-import type { Keypair } from '@iota/iota.js/cryptography';
-import { Ed25519Keypair } from '@iota/iota.js/keypairs/ed25519';
-import { TransactionBlock } from '@iota/iota.js/transactions';
-import {
- fromB64,
- normalizeStructTag,
- normalizeIotaAddress,
- normalizeIotaObjectId,
- parseStructTag,
- IOTA_TYPE_ARG,
- toB64,
-} from '@iota/iota.js/utils';
-
-import type { ZkSendLinkBuilderOptions } from './builder.js';
-import { ZkSendLinkBuilder } from './builder.js';
-import type { LinkAssets } from './utils.js';
-import { getAssetsFromTxnBlock, isOwner, ownedAfterChange } from './utils.js';
-import type { ZkBagContractOptions } from './zk-bag.js';
-import { MAINNET_CONTRACT_IDS, ZkBag } from './zk-bag.js';
-
-const DEFAULT_ZK_SEND_LINK_OPTIONS = {
- host: 'https://zksend.com',
- path: '/claim',
- network: 'mainnet' as const,
- claimApi: 'https://zksend.com/api',
-};
-
-const IOTA_COIN_TYPE = normalizeStructTag(IOTA_TYPE_ARG);
-const IOTA_COIN_OBJECT_TYPE = normalizeStructTag('0x2::coin::Coin<0x2::iota::IOTA>');
-
-export type ZkSendLinkOptions = {
- claimApi?: string;
- keypair?: Keypair;
- client?: IotaClient;
- network?: 'mainnet' | 'testnet';
- host?: string;
- path?: string;
- address?: string;
- isContractLink: boolean;
- contract?: ZkBagContractOptions | null;
-} & (
- | {
- address: string;
- keypair?: never;
- }
- | {
- keypair: Keypair;
- address?: never;
- }
-);
-
-export class ZkSendLink {
- address: string;
- keypair?: Keypair;
- creatorAddress?: string;
- assets?: LinkAssets;
- claimed?: boolean;
-
- #client: IotaClient;
- #contract?: ZkBag;
- #claimApi: string;
- #network: 'mainnet' | 'testnet';
- #host?: string;
- #path?: string;
-
- // State for non-contract based links
- #gasCoin?: CoinStruct;
- #hasIota = false;
- #ownedObjects: {
- objectId: string;
- version: string;
- digest: string;
- type: string;
- }[] = [];
-
- constructor({
- network = DEFAULT_ZK_SEND_LINK_OPTIONS.network,
- claimApi = DEFAULT_ZK_SEND_LINK_OPTIONS.claimApi,
- client = new IotaClient({ url: getFullnodeUrl(network) }),
- keypair,
- contract = network === 'mainnet' ? MAINNET_CONTRACT_IDS : null,
- address,
- host,
- path,
- isContractLink,
- }: ZkSendLinkOptions) {
- if (!keypair && !address) {
- throw new Error('Either keypair or address must be provided');
- }
-
- this.#client = client;
- this.keypair = keypair;
- this.address = address ?? keypair!.toIotaAddress();
- this.#claimApi = claimApi;
- this.#network = network;
- this.#host = host;
- this.#path = path;
-
- if (isContractLink) {
- if (!contract) {
- throw new Error('Contract options are required for contract based links');
- }
-
- this.#contract = new ZkBag(contract.packageId, contract);
- }
- }
-
- static async fromUrl(
- url: string,
- options: Omit = {},
- ) {
- const parsed = new URL(url);
- const isContractLink = parsed.hash.startsWith('#$');
-
- let link: ZkSendLink;
- if (isContractLink) {
- const keypair = Ed25519Keypair.fromSecretKey(fromB64(parsed.hash.slice(2)));
- link = new ZkSendLink({
- ...options,
- keypair,
- host: `${parsed.protocol}//${parsed.host}`,
- path: parsed.pathname,
- isContractLink: true,
- });
- } else {
- const keypair = Ed25519Keypair.fromSecretKey(
- fromB64(isContractLink ? parsed.hash.slice(2) : parsed.hash.slice(1)),
- );
-
- link = new ZkSendLink({
- ...options,
- keypair,
- host: `${parsed.protocol}//${parsed.host}`,
- path: parsed.pathname,
- isContractLink: false,
- });
- }
-
- await link.loadAssets();
-
- return link;
- }
-
- static async fromAddress(
- address: string,
- options: Omit,
- ) {
- const link = new ZkSendLink({
- ...options,
- address,
- isContractLink: true,
- });
-
- await link.loadAssets();
-
- return link;
- }
-
- async loadAssets() {
- if (this.#contract) {
- await this.#loadBag();
- } else {
- await this.#loadOwnedObjects();
- }
- }
-
- async claimAssets(address: string) {
- if (!this.keypair) {
- throw new Error('Cannot claim assets without links keypair');
- }
-
- if (this.claimed) {
- throw new Error('Assets have already been claimed');
- }
-
- if (!this.#contract) {
- return this.#client.signAndExecuteTransactionBlock({
- transactionBlock: this.createClaimTransaction(address),
- signer: this.keypair,
- });
- }
-
- if (!this.assets) {
- await this.#loadBag();
- }
-
- const txb = this.createClaimTransaction(address);
-
- const { digest } = await this.#executeSponsoredTransactionBlock(
- await this.#createSponsoredTransactionBlock(txb, address, this.keypair.toIotaAddress()),
- this.keypair,
- );
-
- return this.#client.waitForTransactionBlock({ digest });
- }
-
- createClaimTransaction(
- address: string,
- {
- reclaim,
- }: {
- reclaim?: boolean;
- } = {},
- ) {
- if (!this.#contract) {
- return this.#createNonContractClaimTransaction(address);
- }
-
- if (!this.keypair && !reclaim) {
- throw new Error('Cannot claim assets without the links keypair');
- }
-
- const txb = new TransactionBlock();
- const sender = reclaim ? address : this.keypair!.toIotaAddress();
- txb.setSender(sender);
-
- const store = txb.object(this.#contract.ids.bagStoreId);
-
- const [bag, proof] = reclaim
- ? this.#contract.reclaim(txb, { arguments: [store, this.address] })
- : this.#contract.init_claim(txb, { arguments: [store] });
-
- const objectsToTransfer = [];
-
- const objects = [...(this.assets?.coins ?? []), ...(this.assets?.nfts ?? [])];
-
- for (const object of objects) {
- objectsToTransfer.push(
- this.#contract.claim(txb, {
- arguments: [
- bag,
- proof,
- txb.receivingRef({
- objectId: object.objectId,
- version: object.version,
- digest: object.digest,
- }),
- ],
- typeArguments: [object.type],
- }),
- );
- }
-
- this.#contract.finalize(txb, { arguments: [bag, proof] });
- if (objectsToTransfer.length > 0) {
- txb.transferObjects(objectsToTransfer, address);
- }
-
- return txb;
- }
-
- async createRegenerateTransaction(
- sender: string,
- options: Omit = {},
- ) {
- if (!this.assets) {
- await this.#loadBag();
- }
-
- if (this.claimed) {
- throw new Error('Assets have already been claimed');
- }
-
- if (!this.#contract) {
- throw new Error('Regenerating non-contract based links is not supported');
- }
-
- const txb = new TransactionBlock();
- txb.setSender(sender);
-
- const store = txb.object(this.#contract.ids.bagStoreId);
-
- const newLinkKp = Ed25519Keypair.generate();
-
- const newLink = new ZkSendLinkBuilder({
- ...options,
- sender,
- client: this.#client,
- contract: this.#contract.ids,
- host: this.#host,
- path: this.#path,
- keypair: newLinkKp,
- });
-
- const to = txb.pure.address(newLinkKp.toIotaAddress());
-
- this.#contract.update_receiver(txb, { arguments: [store, this.address, to] });
-
- return {
- url: newLink.getLink(),
- transactionBlock: txb,
- };
- }
-
- async #loadBag() {
- if (!this.#contract) {
- return;
- }
-
- this.assets = {
- balances: [],
- nfts: [],
- coins: [],
- };
-
- const bagField = await this.#client.getDynamicFieldObject({
- parentId: this.#contract.ids.bagStoreTableId,
- name: {
- type: 'address',
- value: this.address,
- },
- });
-
- if (!bagField.data) {
- this.claimed = true;
- await this.#loadClaimedAssets();
-
- return;
- } else {
- this.claimed = false;
- }
-
- const itemIds: string[] | undefined = (bagField as any).data?.content?.fields?.value?.fields
- ?.item_ids.fields.contents;
-
- this.creatorAddress = (bagField as any).data?.content?.fields?.value?.fields?.owner;
-
- if (!itemIds) {
- throw new Error('Invalid bag field');
- }
-
- const objectsResponse = await this.#client.multiGetObjects({
- ids: itemIds,
- options: {
- showType: true,
- showContent: true,
- },
- });
-
- const balances = new Map<
- string,
- {
- coinType: string;
- amount: bigint;
- }
- >();
-
- objectsResponse.forEach((object, i) => {
- if (!object.data || !object.data.type) {
- throw new Error(`Failed to load claimable object ${itemIds[i]}`);
- }
-
- const type = parseStructTag(normalizeStructTag(object.data.type));
-
- if (
- type.address === normalizeIotaAddress('0x2') &&
- type.module === 'coin' &&
- type.name === 'Coin'
- ) {
- this.assets!.coins.push({
- objectId: object.data.objectId,
- type: object.data.type,
- version: object.data.version,
- digest: object.data.digest,
- });
-
- if (object.data.content?.dataType === 'moveObject') {
- const amount = BigInt(
- (object.data.content.fields as Record).balance,
- );
- const coinType = normalizeStructTag(
- parseStructTag(object.data.content.type).typeParams[0],
- );
- if (!balances.has(coinType)) {
- balances.set(coinType, { coinType, amount });
- } else {
- balances.get(coinType)!.amount += amount;
- }
- }
- } else {
- this.assets!.nfts.push({
- objectId: object.data.objectId,
- type: object.data.type,
- version: object.data.version,
- digest: object.data.digest,
- });
- }
- });
-
- this.assets.balances = [...balances.values()];
- }
-
- async #loadClaimedAssets() {
- const result = await this.#client.queryTransactionBlocks({
- limit: 1,
- filter: {
- FromAddress: this.address,
- },
- options: {
- showObjectChanges: true,
- showBalanceChanges: true,
- showInput: true,
- },
- });
-
- if (!result?.data[0]) {
- return;
- }
-
- const [txb] = result.data;
-
- if (txb.transaction?.data.transaction.kind !== 'ProgrammableTransaction') {
- return;
- }
-
- const transfer = txb.transaction.data.transaction.transactions.findLast(
- (tx): tx is Extract =>
- 'TransferObjects' in tx,
- );
-
- if (!transfer) {
- return;
- }
-
- const receiverArg = transfer.TransferObjects[1];
-
- if (!(typeof receiverArg === 'object' && 'Input' in receiverArg)) {
- return;
- }
-
- const input = txb.transaction.data.transaction.inputs[receiverArg.Input];
-
- if (input.type !== 'pure') {
- return;
- }
-
- const receiver =
- typeof input.value === 'string'
- ? input.value
- : bcs.Address.parse(new Uint8Array((input.value as PureArg).Pure));
-
- this.assets = getAssetsFromTxnBlock({
- transactionBlock: txb,
- address: receiver,
- isSent: false,
- });
- }
-
- async #createSponsoredTransactionBlock(txb: TransactionBlock, claimer: string, sender: string) {
- return this.#fetch<{ digest: string; bytes: string }>('transaction-blocks/sponsor', {
- method: 'POST',
- body: JSON.stringify({
- network: this.#network,
- sender,
- claimer,
- transactionBlockKindBytes: toB64(
- await txb.build({
- onlyTransactionKind: true,
- client: this.#client,
- // Theses limits will get verified during the final transaction construction, so we can safely ignore them here:
- limits: {
- maxGasObjects: Infinity,
- maxPureArgumentSize: Infinity,
- maxTxGas: Infinity,
- maxTxSizeBytes: Infinity,
- },
- }),
- ),
- }),
- });
- }
-
- async #executeSponsoredTransactionBlock(
- input: { digest: string; bytes: string },
- keypair: Keypair,
- ) {
- return this.#fetch<{ digest: string }>(`transaction-blocks/sponsor/${input.digest}`, {
- method: 'POST',
- body: JSON.stringify({
- signature: (await keypair.signTransactionBlock(fromB64(input.bytes))).signature,
- }),
- });
- }
-
- async #fetch(path: string, init: RequestInit): Promise {
- const res = await fetch(`${this.#claimApi}/v1/${path}`, {
- ...init,
- headers: {
- ...init.headers,
- 'Content-Type': 'application/json',
- },
- });
-
- if (!res.ok) {
- console.error(await res.text());
- throw new Error(`Request to claim API failed with status code ${res.status}`);
- }
-
- const { data } = await res.json();
-
- return data as T;
- }
-
- async #listNonContractClaimableAssets() {
- const balances: {
- coinType: string;
- amount: bigint;
- }[] = [];
-
- const nfts: {
- objectId: string;
- type: string;
- version: string;
- digest: string;
- }[] = [];
-
- const coins: {
- objectId: string;
- type: string;
- version: string;
- digest: string;
- }[] = [];
-
- if (this.#ownedObjects.length === 0 && !this.#hasIota) {
- return {
- balances,
- nfts,
- coins,
- };
- }
-
- const address = new Ed25519Keypair().toIotaAddress();
- const normalizedAddress = normalizeIotaAddress(address);
-
- const txb = this.createClaimTransaction(normalizedAddress);
-
- if (this.#gasCoin || !this.#hasIota) {
- txb.setGasPayment([]);
- }
-
- const dryRun = await this.#client.dryRunTransactionBlock({
- transactionBlock: await txb.build({ client: this.#client }),
- });
-
- dryRun.balanceChanges.forEach((balanceChange) => {
- if (
- BigInt(balanceChange.amount) > 0n &&
- isOwner(balanceChange.owner, normalizedAddress)
- ) {
- balances.push({
- coinType: normalizeStructTag(balanceChange.coinType),
- amount: BigInt(balanceChange.amount),
- });
- }
- });
-
- dryRun.objectChanges.forEach((objectChange) => {
- if ('objectType' in objectChange) {
- const type = parseStructTag(objectChange.objectType);
-
- if (
- type.address === normalizeIotaAddress('0x2') &&
- type.module === 'coin' &&
- type.name === 'Coin'
- ) {
- if (ownedAfterChange(objectChange, normalizedAddress)) {
- coins.push(objectChange);
- }
- return;
- }
- }
-
- if (ownedAfterChange(objectChange, normalizedAddress)) {
- nfts.push(objectChange);
- }
- });
-
- return {
- balances,
- nfts,
- coins,
- };
- }
-
- #createNonContractClaimTransaction(address: string) {
- if (!this.keypair) {
- throw new Error('Cannot claim assets without the links keypair');
- }
-
- const txb = new TransactionBlock();
- txb.setSender(this.keypair.toIotaAddress());
-
- const objectsToTransfer = this.#ownedObjects
- .filter((object) => {
- if (this.#gasCoin) {
- if (object.objectId === this.#gasCoin.coinObjectId) {
- return false;
- }
- } else if (object.type === IOTA_COIN_OBJECT_TYPE) {
- return false;
- }
-
- return true;
- })
- .map((object) => txb.object(object.objectId));
-
- if (this.#gasCoin && this.creatorAddress) {
- txb.transferObjects([txb.gas], this.creatorAddress);
- } else {
- objectsToTransfer.push(txb.gas);
- }
-
- if (objectsToTransfer.length > 0) {
- txb.transferObjects(objectsToTransfer, address);
- }
-
- return txb;
- }
-
- async #loadOwnedObjects() {
- this.assets = {
- nfts: [],
- balances: [],
- coins: [],
- };
-
- let nextCursor: string | null | undefined;
- do {
- const ownedObjects = await this.#client.getOwnedObjects({
- cursor: nextCursor,
- owner: this.address,
- options: {
- showType: true,
- showContent: true,
- },
- });
-
- // RPC response returns cursor even if there are no more pages
- nextCursor = ownedObjects.hasNextPage ? ownedObjects.nextCursor : null;
- for (const object of ownedObjects.data) {
- if (object.data) {
- this.#ownedObjects.push({
- objectId: normalizeIotaObjectId(object.data.objectId),
- version: object.data.version,
- digest: object.data.digest,
- type: normalizeStructTag(object.data.type!),
- });
- }
- }
- } while (nextCursor);
-
- const coins = await this.#client.getCoins({
- coinType: IOTA_COIN_TYPE,
- owner: this.address,
- });
-
- this.#hasIota = coins.data.length > 0;
- this.#gasCoin = coins.data.find((coin) => BigInt(coin.balance) % 1000n === 987n);
-
- const result = await this.#client.queryTransactionBlocks({
- limit: 1,
- order: 'ascending',
- filter: {
- ToAddress: this.address,
- },
- options: {
- showInput: true,
- showBalanceChanges: true,
- showObjectChanges: true,
- },
- });
-
- this.creatorAddress = result.data[0]?.transaction?.data.sender;
-
- if (this.#hasIota || this.#ownedObjects.length > 0) {
- this.claimed = false;
- this.assets = await this.#listNonContractClaimableAssets();
- } else if (result.data[0]) {
- this.claimed = true;
- await this.#loadClaimedAssets();
- }
- }
-}
diff --git a/sdk/zksend/src/links/list-created-links.ts b/sdk/zksend/src/links/list-created-links.ts
deleted file mode 100644
index 59478e635f1..00000000000
--- a/sdk/zksend/src/links/list-created-links.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { bcs } from '@iota/iota.js/bcs';
-import type { IotaClient } from '@iota/iota.js/client';
-import { IotaGraphQLClient } from '@iota/iota.js/graphql';
-import { graphql } from '@iota/iota.js/graphql/schemas/2024-01';
-import { fromB64, normalizeIotaAddress } from '@iota/iota.js/utils';
-
-import { ZkSendLink } from './claim.js';
-import type { ZkBagContractOptions } from './zk-bag.js';
-import { MAINNET_CONTRACT_IDS } from './zk-bag.js';
-
-const ListCreatedLinksQuery = graphql(`
- query listCreatedLinks($address: IotaAddress!, $function: String!, $cursor: String) {
- transactionBlocks(
- last: 10
- before: $cursor
- filter: { signAddress: $address, function: $function, kind: PROGRAMMABLE_TX }
- ) {
- pageInfo {
- startCursor
- hasPreviousPage
- }
- nodes {
- effects {
- timestamp
- }
- digest
- kind {
- __typename
- ... on ProgrammableTransactionBlock {
- inputs(first: 10) {
- nodes {
- __typename
- ... on Pure {
- bytes
- }
- }
- }
- transactions(first: 10) {
- nodes {
- __typename
- ... on MoveCallTransaction {
- module
- functionName
- package
- arguments {
- __typename
- ... on Input {
- ix
- }
- }
- }
- }
- }
- }
- }
- }
- }
- }
-`);
-
-export async function listCreatedLinks({
- address,
- cursor,
- network,
- contract = MAINNET_CONTRACT_IDS,
- ...linkOptions
-}: {
- address: string;
- contract?: ZkBagContractOptions;
- cursor?: string;
- network?: 'mainnet' | 'testnet';
- // Link options:
- host?: string;
- path?: string;
- client?: IotaClient;
-}) {
- const gqlClient = new IotaGraphQLClient({
- url:
- network === 'testnet'
- ? 'https://iota-testnet.mystenlabs.com/graphql'
- : 'https://iota-mainnet.mystenlabs.com/graphql',
- });
-
- const packageId = normalizeIotaAddress(contract.packageId);
-
- const page = await gqlClient.query({
- query: ListCreatedLinksQuery,
- variables: {
- address,
- cursor,
- function: `${packageId}::zk_bag::new`,
- },
- });
-
- const transactionBlocks = page.data?.transactionBlocks;
-
- if (!transactionBlocks || page.errors?.length) {
- throw new Error('Failed to load created links');
- }
-
- const links = (
- await Promise.all(
- transactionBlocks.nodes.map(async (node) => {
- if (node.kind?.__typename !== 'ProgrammableTransactionBlock') {
- throw new Error('Invalid transaction block');
- }
-
- const fn = node.kind.transactions.nodes.find(
- (fn) =>
- fn.__typename === 'MoveCallTransaction' &&
- fn.package === packageId &&
- fn.module === 'zk_bag' &&
- fn.functionName === 'new',
- );
-
- if (fn?.__typename !== 'MoveCallTransaction') {
- return null;
- }
-
- const addressArg = fn.arguments[1];
-
- if (addressArg.__typename !== 'Input') {
- throw new Error('Invalid address argument');
- }
-
- const input = node.kind.inputs.nodes[addressArg.ix];
-
- if (input.__typename !== 'Pure') {
- throw new Error('Expected Address input to be a Pure value');
- }
-
- const address = bcs.Address.parse(fromB64(input.bytes as string));
-
- const link = new ZkSendLink({
- network,
- address,
- contract,
- isContractLink: true,
- ...linkOptions,
- });
-
- await link.loadAssets();
-
- return {
- link,
- claimed: !!link.claimed,
- assets: link.assets!,
- digest: node.digest,
- // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
- createdAt: node.effects?.timestamp!,
- };
- }),
- )
- ).reverse();
-
- return {
- cursor: transactionBlocks.pageInfo.startCursor,
- hasNextPage: transactionBlocks.pageInfo.hasPreviousPage,
- links: links.filter((link): link is NonNullable => link !== null),
- };
-}
diff --git a/sdk/zksend/src/links/utils.ts b/sdk/zksend/src/links/utils.ts
deleted file mode 100644
index c49ba9742d1..00000000000
--- a/sdk/zksend/src/links/utils.ts
+++ /dev/null
@@ -1,200 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import type {
- ObjectOwner,
- IotaObjectChange,
- IotaTransactionBlockResponse,
-} from '@iota/iota.js/client';
-import type { TransactionBlock } from '@iota/iota.js/transactions';
-import { normalizeStructTag, normalizeIotaAddress, parseStructTag } from '@iota/iota.js/utils';
-
-// eslint-disable-next-line import/no-cycle
-
-export interface LinkAssets {
- balances: {
- coinType: string;
- amount: bigint;
- }[];
-
- nfts: {
- objectId: string;
- type: string;
- version: string;
- digest: string;
- }[];
-
- coins: {
- objectId: string;
- type: string;
- version: string;
- digest: string;
- }[];
-}
-
-export function isClaimTransaction(
- txb: TransactionBlock,
- options: {
- packageId: string;
- },
-) {
- let transfers = 0;
-
- for (const tx of txb.blockData.transactions) {
- switch (tx.kind) {
- case 'TransferObjects':
- // Ensure that we are only transferring results of a claim
- if (!tx.objects.every((o) => o.kind === 'Result' || o.kind === 'NestedResult')) {
- return false;
- }
- transfers++;
- break;
- case 'MoveCall':
- const [packageId, module, fn] = tx.target.split('::');
-
- if (packageId !== options.packageId) {
- return false;
- }
-
- if (module !== 'zk_bag') {
- return false;
- }
-
- if (
- fn !== 'init_claim' &&
- fn !== 'reclaim' &&
- fn !== 'claim' &&
- fn !== 'finalize'
- ) {
- return false;
- }
- break;
- default:
- return false;
- }
- }
-
- return transfers === 1;
-}
-
-export function getAssetsFromTxnBlock({
- transactionBlock,
- address,
- isSent,
-}: {
- transactionBlock: IotaTransactionBlockResponse;
- address: string;
- isSent: boolean;
-}): LinkAssets {
- const normalizedAddress = normalizeIotaAddress(address);
- const balances: {
- coinType: string;
- amount: bigint;
- }[] = [];
-
- const nfts: {
- objectId: string;
- type: string;
- version: string;
- digest: string;
- }[] = [];
-
- const coins: {
- objectId: string;
- type: string;
- version: string;
- digest: string;
- }[] = [];
-
- transactionBlock.balanceChanges?.forEach((change) => {
- const validAmountChange = isSent ? BigInt(change.amount) < 0n : BigInt(change.amount) > 0n;
- if (validAmountChange && isOwner(change.owner, normalizedAddress)) {
- balances.push({
- coinType: normalizeStructTag(change.coinType),
- amount: BigInt(change.amount),
- });
- }
- });
-
- transactionBlock.objectChanges?.forEach((change) => {
- if ('objectType' in change) {
- const type = parseStructTag(change.objectType);
-
- if (
- type.address === normalizeIotaAddress('0x2') &&
- type.module === 'coin' &&
- type.name === 'Coin'
- ) {
- if (
- change.type === 'created' ||
- change.type === 'transferred' ||
- change.type === 'mutated'
- ) {
- coins.push(change);
- }
- return;
- }
- }
-
- if (
- isObjectOwner(change, normalizedAddress, isSent) &&
- (change.type === 'created' ||
- change.type === 'transferred' ||
- change.type === 'mutated')
- ) {
- nfts.push(change);
- }
- });
-
- return {
- balances,
- nfts,
- coins,
- };
-}
-
-function getObjectOwnerFromObjectChange(objectChange: IotaObjectChange, isSent: boolean) {
- if (isSent) {
- return 'owner' in objectChange ? objectChange.owner : null;
- }
-
- return 'recipient' in objectChange ? objectChange.recipient : null;
-}
-
-function isObjectOwner(objectChange: IotaObjectChange, address: string, isSent: boolean) {
- const owner = getObjectOwnerFromObjectChange(objectChange, isSent);
-
- if (isSent) {
- return owner && typeof owner === 'object' && 'AddressOwner' in owner;
- }
-
- return ownedAfterChange(objectChange, address);
-}
-
-export function ownedAfterChange(
- objectChange: IotaObjectChange,
- address: string,
-): objectChange is Extract {
- if (objectChange.type === 'transferred' && isOwner(objectChange.recipient, address)) {
- return true;
- }
-
- if (
- (objectChange.type === 'created' || objectChange.type === 'mutated') &&
- isOwner(objectChange.owner, address)
- ) {
- return true;
- }
-
- return false;
-}
-
-export function isOwner(owner: ObjectOwner, address: string): owner is { AddressOwner: string } {
- return (
- owner &&
- typeof owner === 'object' &&
- 'AddressOwner' in owner &&
- normalizeIotaAddress(owner.AddressOwner) === address
- );
-}
diff --git a/sdk/zksend/src/links/zk-bag.ts b/sdk/zksend/src/links/zk-bag.ts
deleted file mode 100644
index 32a1bd92d57..00000000000
--- a/sdk/zksend/src/links/zk-bag.ts
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import type {
- TransactionArgument,
- TransactionBlock,
- TransactionObjectArgument,
-} from '@iota/iota.js/transactions';
-
-export interface ZkBagContractOptions {
- packageId: string;
- bagStoreId: string;
- bagStoreTableId: string;
-}
-
-export const MAINNET_CONTRACT_IDS: ZkBagContractOptions = {
- packageId: '0x5bb7d0bb3240011336ca9015f553b2646302a4f05f821160344e9ec5a988f740',
- bagStoreId: '0x65b215a3f2a951c94313a89c43f0adbd2fd9ea78a0badf81e27d1c9868a8b6fe',
- bagStoreTableId: '0x616db54ca564660cd58e36a4548be68b289371ef2611485c62c374a60960084e',
-};
-
-export class ZkBag {
- #package: string;
- #module = 'zk_bag' as const;
- ids: IDs;
-
- constructor(packageAddress: string, ids: IDs) {
- this.#package = packageAddress;
- this.ids = ids;
- }
-
- new(
- txb: TransactionBlock,
- {
- arguments: [store, receiver],
- }: {
- arguments: [
- store: TransactionObjectArgument | string,
- receiver: TransactionArgument | string,
- ];
- },
- ) {
- txb.moveCall({
- target: `${this.#package}::${this.#module}::new`,
- arguments: [
- txb.object(store),
- typeof receiver === 'string' ? txb.pure.address(receiver) : receiver,
- ],
- });
- }
-
- add(
- txb: TransactionBlock,
- {
- arguments: [store, receiver, item],
- typeArguments,
- }: {
- arguments: [
- store: TransactionObjectArgument | string,
- receiver: TransactionArgument | string,
- item: TransactionObjectArgument | string,
- ];
- typeArguments: [string];
- },
- ): Extract {
- return txb.moveCall({
- target: `${this.#package}::${this.#module}::add`,
- arguments: [
- txb.object(store),
- typeof receiver === 'string' ? txb.pure.address(receiver) : receiver,
- txb.object(item),
- ],
- typeArguments: typeArguments,
- });
- }
-
- init_claim(
- txb: TransactionBlock,
- {
- arguments: [store],
- }: {
- arguments: [store: TransactionObjectArgument | string];
- },
- ) {
- const [bag, claimProof] = txb.moveCall({
- target: `${this.#package}::${this.#module}::init_claim`,
- arguments: [txb.object(store)],
- });
-
- return [bag, claimProof] as const;
- }
-
- reclaim(
- txb: TransactionBlock,
- {
- arguments: [store, receiver],
- }: {
- arguments: [
- store: TransactionObjectArgument | string,
- receiver: TransactionArgument | string,
- ];
- },
- ) {
- const [bag, claimProof] = txb.moveCall({
- target: `${this.#package}::${this.#module}::reclaim`,
- arguments: [
- txb.object(store),
- typeof receiver === 'string' ? txb.pure.address(receiver) : receiver,
- ],
- });
-
- return [bag, claimProof] as const;
- }
-
- claim(
- txb: TransactionBlock,
- {
- arguments: [bag, claim, id],
- typeArguments,
- }: {
- arguments: [
- bag: TransactionObjectArgument | string,
- claim: Extract,
- id: TransactionObjectArgument | string,
- ];
- typeArguments: [string];
- },
- ): Extract {
- return txb.moveCall({
- target: `${this.#package}::${this.#module}::claim`,
- arguments: [
- txb.object(bag),
- txb.object(claim),
- typeof id === 'string' ? txb.object(id) : id,
- ],
- typeArguments,
- });
- }
-
- finalize(
- txb: TransactionBlock,
- {
- arguments: [bag, claim],
- }: {
- arguments: [
- bag: TransactionObjectArgument | string,
- claim: Extract,
- ];
- },
- ) {
- txb.moveCall({
- target: `${this.#package}::${this.#module}::finalize`,
- arguments: [txb.object(bag), txb.object(claim)],
- });
- }
-
- update_receiver(
- txb: TransactionBlock,
- {
- arguments: [bag, from, to],
- }: {
- arguments: [
- bag: TransactionObjectArgument | string,
- from: TransactionArgument | string,
- to: TransactionArgument | string,
- ];
- },
- ) {
- txb.moveCall({
- target: `${this.#package}::${this.#module}::update_receiver`,
- arguments: [
- txb.object(bag),
- typeof from === 'string' ? txb.pure.address(from) : from,
- typeof to === 'string' ? txb.pure.address(to) : to,
- ],
- });
- }
-}
diff --git a/sdk/zksend/src/utils/withResolvers.ts b/sdk/zksend/src/utils/withResolvers.ts
deleted file mode 100644
index 9e8f4de3f28..00000000000
--- a/sdk/zksend/src/utils/withResolvers.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-export interface Resolvers {
- promise: Promise;
- reject: (error: Error) => void;
- resolve: (value: T) => void;
-}
-
-export function withResolvers(): Resolvers {
- let resolve: (value: T) => void;
- let reject: (error: Error) => void;
-
- const promise = new Promise((res, rej) => {
- resolve = res;
- reject = rej;
- });
-
- return { promise, reject: reject!, resolve: resolve! };
-}
diff --git a/sdk/zksend/src/wallet.ts b/sdk/zksend/src/wallet.ts
deleted file mode 100644
index 6169c6306f5..00000000000
--- a/sdk/zksend/src/wallet.ts
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { bcs } from '@iota/iota.js/bcs';
-import { toB64 } from '@iota/iota.js/utils';
-import type {
- StandardConnectFeature,
- StandardConnectMethod,
- StandardDisconnectFeature,
- StandardDisconnectMethod,
- StandardEventsFeature,
- StandardEventsListeners,
- StandardEventsOnMethod,
- IotaSignPersonalMessageFeature,
- IotaSignPersonalMessageMethod,
- IotaSignTransactionBlockFeature,
- IotaSignTransactionBlockMethod,
- Wallet,
-} from '@iota/wallet-standard';
-import { getWallets, ReadonlyWalletAccount, SUPPORTED_CHAINS } from '@iota/wallet-standard';
-import type { Emitter } from 'mitt';
-import mitt from 'mitt';
-
-import { DEFAULT_ZKSEND_ORIGIN, ZkSendPopup } from './channel/index.js';
-
-type WalletEventsMap = {
- [E in keyof StandardEventsListeners]: Parameters[0];
-};
-
-const ZKSEND_RECENT_ADDRESS_KEY = 'zksend:recentAddress';
-
-export const ZKSEND_WALLET_NAME = 'zkSend' as const;
-
-export class ZkSendWallet implements Wallet {
- #events: Emitter;
- #accounts: ReadonlyWalletAccount[];
- #origin: string;
- #name: string;
-
- get name() {
- return ZKSEND_WALLET_NAME;
- }
-
- get icon() {
- return 'data:image/svg+xml;base64,PHN2ZyBmaWxsPSJub25lIiBoZWlnaHQ9IjMyIiB2aWV3Qm94PSIwIDAgMzIgMzIiIHdpZHRoPSIzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGNsaXBQYXRoIGlkPSJhIj48cmVjdCBoZWlnaHQ9IjMyIiByeD0iMiIgd2lkdGg9IjMyIi8+PC9jbGlwUGF0aD48ZyBjbGlwLXBhdGg9InVybCgjYSkiPjxyZWN0IGZpbGw9IiNmZmYiIGhlaWdodD0iMzIiIHJ4PSIyIiB3aWR0aD0iMzIiLz48cGF0aCBkPSJtMCAwaDMydjMyaC0zMnoiIGZpbGw9IiNkNDA1NTEiLz48cGF0aCBkPSJtNS42NjgyNSAyNS4yNDkxYy0uNzgyNjMtLjc4MjctLjc4MDgxLTIuMDUyMS4wMDQwNi0yLjgzMjVsMTYuNjA1MjktMTYuNTEwNDdjLjc4MTctLjc3NzIzIDIuMDQ0OS0uNzc1NDMgMi44MjQzLjAwNDA0bC44Mzg3LjgzODYyYy43ODI1Ljc4MjUxLjc4MDggMi4wNTE3NC0uMDAzOCAyLjgzMjE4bC0xNi42MDE4OCAxNi41MTM4M2MtLjc4MTY1Ljc3NzUtMi4wNDUwOC43NzU4LTIuODI0NjYtLjAwMzd6bTUuNDQzMzUtMTUuOTExNjZjLTEuODA5NzIuMDUzNjctMi43NTM3MS0yLjEzMzA5LTEuNDczNDctMy40MTMzM2wuODM4MzctLjgzODMyYy4zNzUtLjM3NTA4Ljg4MzctLjU4NTc5IDEuNDE0Mi0uNTg1NzloMTMuNDc5N2MxLjEwNDYgMCAyIC44OTU0MyAyIDJ2MTMuNDc5N2MwIC41MzA1LS4yMTA3IDEuMDM5Mi0uNTg1OCAxLjQxNDJsLS44MjY5LjgyN2MtMS4yODE4IDEuMjgxOC0zLjQ3MDkuMzMzOS0zLjQxMzItMS40Nzc5bC4zMDY2LTkuNjI5OWMuMDM2Ny0xLjE1MjI3LS45MDU5LTIuMDk2OS0yLjA1ODMtMi4wNjI3M3oiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+' as const;
- }
-
- get version() {
- return '1.0.0' as const;
- }
-
- get chains() {
- return SUPPORTED_CHAINS;
- }
-
- get accounts() {
- return this.#accounts;
- }
-
- get features(): StandardConnectFeature &
- StandardDisconnectFeature &
- StandardEventsFeature &
- IotaSignTransactionBlockFeature &
- IotaSignPersonalMessageFeature {
- return {
- 'standard:connect': {
- version: '1.0.0',
- connect: this.#connect,
- },
- 'standard:disconnect': {
- version: '1.0.0',
- disconnect: this.#disconnect,
- },
- 'standard:events': {
- version: '1.0.0',
- on: this.#on,
- },
- 'iota:signTransactionBlock': {
- version: '1.0.0',
- signTransactionBlock: this.#signTransactionBlock,
- },
- 'iota:signPersonalMessage': {
- version: '1.0.0',
- signPersonalMessage: this.#signPersonalMessage,
- },
- };
- }
-
- constructor({
- name,
- address,
- origin = DEFAULT_ZKSEND_ORIGIN,
- }: {
- origin?: string;
- address?: string | null;
- name: string;
- }) {
- this.#accounts = [];
- this.#events = mitt();
- this.#origin = origin;
- this.#name = name;
-
- if (address) {
- this.#setAccount(address);
- }
- }
-
- #signTransactionBlock: IotaSignTransactionBlockMethod = async ({
- transactionBlock,
- account,
- }) => {
- transactionBlock.setSenderIfNotSet(account.address);
-
- const data = transactionBlock.serialize();
-
- const popup = new ZkSendPopup({ name: this.#name, origin: this.#origin });
- const response = await popup.createRequest({
- type: 'sign-transaction-block',
- data,
- address: account.address,
- });
-
- return {
- transactionBlockBytes: response.bytes,
- signature: response.signature,
- };
- };
-
- #signPersonalMessage: IotaSignPersonalMessageMethod = async ({ message, account }) => {
- const bytes = toB64(bcs.vector(bcs.u8()).serialize(message).toBytes());
- const popup = new ZkSendPopup({ name: this.#name, origin: this.#origin });
- const response = await popup.createRequest({
- type: 'sign-personal-message',
- bytes,
- address: account.address,
- });
-
- return {
- bytes,
- signature: response.signature,
- };
- };
-
- #on: StandardEventsOnMethod = (event, listener) => {
- this.#events.on(event, listener);
- return () => this.#events.off(event, listener);
- };
-
- #setAccount(address?: string) {
- if (address) {
- this.#accounts = [
- new ReadonlyWalletAccount({
- address,
- chains: [SUPPORTED_CHAINS[0]],
- features: ['iota:signTransactionBlock', 'iota:signPersonalMessage'],
- // NOTE: zkSend doesn't support getting public keys, and zkLogin accounts don't have meaningful public keys anyway
- publicKey: new Uint8Array(),
- }),
- ];
-
- localStorage.setItem(ZKSEND_RECENT_ADDRESS_KEY, address);
- } else {
- this.#accounts = [];
- }
-
- this.#events.emit('change', { accounts: this.accounts });
- }
-
- #connect: StandardConnectMethod = async (input) => {
- if (input?.silent) {
- const address = localStorage.getItem(ZKSEND_RECENT_ADDRESS_KEY);
-
- if (address) {
- this.#setAccount(address);
- }
-
- return { accounts: this.accounts };
- }
-
- const popup = new ZkSendPopup({ name: this.#name, origin: this.#origin });
- const response = await popup.createRequest({
- type: 'connect',
- });
- if (!('address' in response)) {
- throw new Error('Unexpected response');
- }
-
- this.#setAccount(response.address);
-
- return { accounts: this.accounts };
- };
-
- #disconnect: StandardDisconnectMethod = async () => {
- localStorage.removeItem(ZKSEND_RECENT_ADDRESS_KEY);
- this.#setAccount();
- };
-}
-
-export function registerZkSendWallet(
- name: string,
- {
- origin,
- }: {
- origin?: string;
- },
-) {
- const wallets = getWallets();
-
- let addressFromRedirect: string | null = null;
- try {
- const params = new URLSearchParams(window.location.search);
- addressFromRedirect = params.get('zksend_address');
- } catch {
- // Ignore errors
- }
-
- const wallet = new ZkSendWallet({
- name,
- origin,
- address: addressFromRedirect,
- });
-
- const unregister = wallets.register(wallet);
-
- return {
- wallet,
- unregister,
- addressFromRedirect,
- };
-}
diff --git a/sdk/zksend/tsconfig.esm.json b/sdk/zksend/tsconfig.esm.json
deleted file mode 100644
index df141cc11d4..00000000000
--- a/sdk/zksend/tsconfig.esm.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "compilerOptions": {
- "module": "ESNext",
- "outDir": "dist/esm"
- }
-}
diff --git a/sdk/zksend/tsconfig.json b/sdk/zksend/tsconfig.json
deleted file mode 100644
index 27d3d39311b..00000000000
--- a/sdk/zksend/tsconfig.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../build-scripts/tsconfig.shared.json",
- "include": ["src"],
- "compilerOptions": {
- "module": "CommonJS",
- "outDir": "dist/cjs",
- "isolatedModules": true,
- "rootDir": "src"
- },
- "references": [{ "path": "../wallet-standard" }, { "path": "../typescript" }]
-}
diff --git a/sdk/zksend/typedoc.json b/sdk/zksend/typedoc.json
deleted file mode 100644
index a58ce5a936e..00000000000
--- a/sdk/zksend/typedoc.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "entryPoints": ["src"],
- "excludeInternal": true,
- "excludePrivate": true,
- "intentionallyNotExported": []
-}
diff --git a/sdk/zksend/vitest.config.ts b/sdk/zksend/vitest.config.ts
deleted file mode 100644
index 3804c4a05d2..00000000000
--- a/sdk/zksend/vitest.config.ts
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) Mysten Labs, Inc.
-// Modifications Copyright (c) 2024 IOTA Stiftung
-// SPDX-License-Identifier: Apache-2.0
-
-import { defineConfig } from 'vitest/config';
-
-export default defineConfig({});