Skip to content

Commit

Permalink
[zksend] Fix detection of claimable balances for single coin links (M…
Browse files Browse the repository at this point in the history
…ystenLabs#16141)

## Description 

Describe the changes or additions included in this PR.

## Test Plan 

How did you test the new or updated feature?

---
If your changes are not user-facing and do not break anything, you can
skip the following section. Otherwise, please briefly describe what has
changed under the Release Notes section.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
hayes-mysten authored Feb 8, 2024
1 parent 220a766 commit a2904e0
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/proud-spoons-move.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mysten/zksend': patch
---

Fix for claimable assets not accounting for cases where claimable balance comes from gas coin
21 changes: 13 additions & 8 deletions sdk/zksend/src/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import { getFullnodeUrl, SuiClient } from '@mysten/sui.js/client';
import type { CoinStruct, ObjectOwner, SuiObjectChange } from '@mysten/sui.js/client';
import { decodeSuiPrivateKey } from '@mysten/sui.js/cryptography';
import type { Keypair, Signer } from '@mysten/sui.js/cryptography';
import { Ed25519Keypair } from '@mysten/sui.js/keypairs/ed25519';
import type { TransactionObjectInput } from '@mysten/sui.js/transactions';
Expand All @@ -14,6 +15,7 @@ import {
normalizeSuiObjectId,
parseStructTag,
SUI_TYPE_ARG,
toB64,
} from '@mysten/sui.js/utils';

interface ZkSendLinkRedirect {
Expand Down Expand Up @@ -97,7 +99,7 @@ export class ZkSendLinkBuilder {
getLink(): string {
const link = new URL(this.#host);
link.pathname = this.#path;
link.hash = this.#keypair.export().privateKey;
link.hash = toB64(decodeSuiPrivateKey(this.#keypair.getSecretKey()).secretKey);

if (this.#redirect) {
link.searchParams.set('redirect_url', this.#redirect.url);
Expand Down Expand Up @@ -239,7 +241,7 @@ export class ZkSendLink {
constructor({
client = DEFAULT_ZK_SEND_LINK_OPTIONS.client,
keypair = new Ed25519Keypair(),
}: ZkSendLinkOptions) {
}: ZkSendLinkOptions & { linkAddress?: string }) {
this.#client = client;
this.#keypair = keypair;
}
Expand Down Expand Up @@ -272,7 +274,10 @@ export class ZkSendLink {
) {
const normalizedAddress = normalizeSuiAddress(address);
const txb = this.createClaimTransaction(normalizedAddress, options);
txb.setGasPayment([]);

if (this.#gasCoin) {
txb.setGasPayment([]);
}

const dryRun = await this.#client.dryRunTransactionBlock({
transactionBlock: await txb.build({ client: this.#client }),
Expand Down Expand Up @@ -390,10 +395,11 @@ export class ZkSendLink {
async #loadOwnedObjects() {
this.#ownedObjects = [];
let nextCursor: string | null | undefined;
const owner = this.#keypair.toSuiAddress();
do {
const ownedObjects = await this.#client.getOwnedObjects({
cursor: nextCursor,
owner: this.#keypair.toSuiAddress(),
owner,
options: {
showType: true,
},
Expand All @@ -415,27 +421,26 @@ export class ZkSendLink {

const coins = await this.#client.getCoins({
coinType: SUI_COIN_TYPE,
owner: this.#keypair.toSuiAddress(),
owner,
});

this.#gasCoin = coins.data.find((coin) => BigInt(coin.balance) % 1000n === 987n);
}

async #loadInitialTransactionData() {
const address = this.#keypair.toSuiAddress();
const result = await this.#client.queryTransactionBlocks({
limit: 1,
order: 'ascending',
filter: {
ToAddress: this.#keypair.toSuiAddress(),
ToAddress: address,
},
options: {
showObjectChanges: true,
showInput: true,
},
});

const address = this.#keypair.toSuiAddress();

result.data[0]?.objectChanges?.forEach((objectChange) => {
if (ownedAfterChange(objectChange, address)) {
this.#initiallyOwnedObjects.add(normalizeSuiObjectId(objectChange.objectId));
Expand Down

0 comments on commit a2904e0

Please sign in to comment.