diff --git a/.changeset/proud-spoons-move.md b/.changeset/proud-spoons-move.md new file mode 100644 index 0000000000000..5dccf3827412a --- /dev/null +++ b/.changeset/proud-spoons-move.md @@ -0,0 +1,5 @@ +--- +'@mysten/zksend': patch +--- + +Fix for claimable assets not accounting for cases where claimable balance comes from gas coin diff --git a/sdk/zksend/src/links.ts b/sdk/zksend/src/links.ts index ff4bc1741f89c..feddd644eac2e 100644 --- a/sdk/zksend/src/links.ts +++ b/sdk/zksend/src/links.ts @@ -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'; @@ -14,6 +15,7 @@ import { normalizeSuiObjectId, parseStructTag, SUI_TYPE_ARG, + toB64, } from '@mysten/sui.js/utils'; interface ZkSendLinkRedirect { @@ -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); @@ -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; } @@ -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 }), @@ -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, }, @@ -415,18 +421,19 @@ 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, @@ -434,8 +441,6 @@ export class ZkSendLink { }, }); - const address = this.#keypair.toSuiAddress(); - result.data[0]?.objectChanges?.forEach((objectChange) => { if (ownedAfterChange(objectChange, address)) { this.#initiallyOwnedObjects.add(normalizeSuiObjectId(objectChange.objectId));