Skip to content
This repository was archived by the owner on Mar 26, 2025. It is now read-only.

Commit a67539f

Browse files
authored
Use appropriate payers in derived identity (#351)
* chore: use appropriate payers in derived identity * fix: subtract tx fee when withdrawing everything * feat: expose getCandyMachineSize helper
1 parent bdd0912 commit a67539f

File tree

6 files changed

+61
-68
lines changed

6 files changed

+61
-68
lines changed

packages/js/src/plugins/candyMachineModule/models/CandyMachine.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,3 +430,33 @@ export const toCandyMachineData = (
430430
: null,
431431
};
432432
};
433+
434+
export const getCandyMachineSize = (data: CandyMachineData): number => {
435+
if (data.hiddenSettings) {
436+
return CANDY_MACHINE_HIDDEN_SECTION;
437+
}
438+
439+
// This should not happen as the candy machine input type
440+
// ensures exactly on of them is provided.
441+
assert(
442+
!!data.configLineSettings,
443+
'No config line settings nor hidden settings were provided. ' +
444+
'Please provide one of them.'
445+
);
446+
447+
const itemsAvailable = toBigNumber(data.itemsAvailable).toNumber();
448+
const configLineSize =
449+
data.configLineSettings.nameLength + data.configLineSettings.uriLength;
450+
451+
return Math.ceil(
452+
CANDY_MACHINE_HIDDEN_SECTION +
453+
// Number of currently items inserted.
454+
4 +
455+
// Config line data.
456+
itemsAvailable * configLineSize +
457+
// Bit mask to keep track of which ConfigLines have been added.
458+
(4 + Math.floor(itemsAvailable / 8) + 1) +
459+
// Mint indices.
460+
(4 + itemsAvailable * 4)
461+
);
462+
};

packages/js/src/plugins/candyMachineModule/models/CandyMachineHiddenSection.ts

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import * as beet from '@metaplex-foundation/beet';
2-
import { CandyMachineData } from '@metaplex-foundation/mpl-candy-machine-core';
32
import { CandyMachineConfigLineSettings, CandyMachineItem } from '..';
4-
import { CANDY_MACHINE_HIDDEN_SECTION } from '../constants';
5-
import { assert, removeEmptyChars } from '@/utils';
6-
import { deserializeFeatureFlags, toBigNumber } from '@/types';
3+
import { deserializeFeatureFlags } from '@/types';
4+
import { removeEmptyChars } from '@/utils';
75

86
/** @internal */
97
export type CandyMachineHiddenSection = {
@@ -95,37 +93,6 @@ export const deserializeCandyMachineHiddenSection = (
9593
};
9694
};
9795

98-
/** @internal */
99-
export const getCandyMachineSize = (data: CandyMachineData): number => {
100-
if (data.hiddenSettings) {
101-
return CANDY_MACHINE_HIDDEN_SECTION;
102-
}
103-
104-
// This should not happen as the candy machine input type
105-
// ensures exactly on of them is provided.
106-
assert(
107-
!!data.configLineSettings,
108-
'No config line settings nor hidden settings were provided. ' +
109-
'Please provide one of them.'
110-
);
111-
112-
const itemsAvailable = toBigNumber(data.itemsAvailable).toNumber();
113-
const configLineSize =
114-
data.configLineSettings.nameLength + data.configLineSettings.uriLength;
115-
116-
return Math.ceil(
117-
CANDY_MACHINE_HIDDEN_SECTION +
118-
// Number of currently items inserted.
119-
4 +
120-
// Config line data.
121-
itemsAvailable * configLineSize +
122-
// Bit mask to keep track of which ConfigLines have been added.
123-
(4 + Math.floor(itemsAvailable / 8) + 1) +
124-
// Mint indices.
125-
(4 + itemsAvailable * 4)
126-
);
127-
};
128-
12996
/** @internal */
13097
export const replaceCandyMachineItemPattern = (
13198
value: string,

packages/js/src/plugins/candyMachineModule/operations/createCandyMachine.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import {
77
CandyMachineConfigLineSettings,
88
CandyMachineHiddenSettings,
99
toCandyMachineData,
10+
getCandyMachineSize,
1011
} from '../models';
11-
import { getCandyMachineSize } from '../models/CandyMachineHiddenSection';
1212
import { TransactionBuilder, TransactionBuilderOptions } from '@/utils';
1313
import {
1414
BigNumber,

packages/js/src/plugins/derivedIdentity/DerivedIdentityClient.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
KeypairSigner,
1010
Signer,
1111
SolAmount,
12+
subtractAmounts,
1213
} from '@/types';
1314
import type { Metaplex } from '@/Metaplex';
1415

@@ -59,28 +60,35 @@ export class DerivedIdentityClient implements IdentitySigner, KeypairSigner {
5960

6061
fund(amount: SolAmount) {
6162
this.assertInitialized();
62-
return this.metaplex.system().transferSol({
63-
from: this.originalSigner,
64-
to: this.derivedKeypair.publicKey,
65-
amount,
66-
});
63+
return this.metaplex.system().transferSol(
64+
{
65+
from: this.originalSigner,
66+
to: this.derivedKeypair.publicKey,
67+
amount,
68+
},
69+
{ payer: this.originalSigner }
70+
);
6771
}
6872

6973
withdraw(amount: SolAmount) {
7074
this.assertInitialized();
71-
return this.metaplex.system().transferSol({
72-
from: this.derivedKeypair,
73-
to: this.originalSigner.publicKey,
74-
amount,
75-
});
75+
return this.metaplex.system().transferSol(
76+
{
77+
from: this.derivedKeypair,
78+
to: this.originalSigner.publicKey,
79+
amount,
80+
},
81+
{ payer: this.derivedKeypair }
82+
);
7683
}
7784

7885
async withdrawAll() {
7986
this.assertInitialized();
8087
const balance = await this.metaplex
8188
.rpc()
8289
.getBalance(this.derivedKeypair.publicKey);
83-
return this.withdraw(balance);
90+
const transactionFee = this.metaplex.utils().estimateTransactionFee();
91+
return this.withdraw(subtractAmounts(balance, transactionFee));
8492
}
8593

8694
close(): void {

packages/js/src/plugins/utilsModule/UtilsClient.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ export class UtilsClient {
4444
this.cachedRentPerByte === null
4545
) {
4646
const rentFor0Bytes = await this.metaplex.rpc().getRent(0);
47+
48+
// TODO(loris): Infer from header size in bytes.
4749
const rentFor1Byte = await this.metaplex.rpc().getRent(1);
4850
this.cachedRentPerEmptyAccount = rentFor0Bytes;
4951
this.cachedRentPerByte = subtractAmounts(rentFor1Byte, rentFor0Bytes);

packages/js/test/plugins/derivedIdentity/DerivedIdentityClient.test.ts

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import {
88
KeypairIdentityDriver,
99
sol,
1010
isEqualToAmount,
11-
isLessThanAmount,
12-
isGreaterThanAmount,
1311
} from '@/index';
1412

1513
killStuckProcess();
@@ -162,12 +160,8 @@ test('[derivedIdentity] it can fund the derived identity', async (t: Test) => {
162160
// It's a little less due to the transaction fee.
163161
const { identityBalance, derivedBalance } = await getBalances(mx);
164162
t.ok(
165-
isLessThanAmount(identityBalance, sol(4)),
166-
'identity balance is less than 4'
167-
);
168-
t.ok(
169-
isGreaterThanAmount(identityBalance, sol(3.9)),
170-
'identity balance is greater than 3.9'
163+
isEqualToAmount(identityBalance, sol(4), sol(0.01)),
164+
'identity balance is around 4'
171165
);
172166
t.ok(isEqualToAmount(derivedBalance, sol(1)), 'derived balance is 1');
173167
});
@@ -188,15 +182,11 @@ test('[derivedIdentity] it can withdraw from the derived identity', async (t: Te
188182
// Then we can see that 1 SOL was transferred from the derived identity to the identity.
189183
// It's a little less due to the transaction fee.
190184
const { identityBalance, derivedBalance } = await getBalances(mx);
185+
t.ok(isEqualToAmount(identityBalance, sol(6)), 'identity balance is 6');
191186
t.ok(
192-
isLessThanAmount(identityBalance, sol(6)),
193-
'identity balance is less than 6'
194-
);
195-
t.ok(
196-
isGreaterThanAmount(identityBalance, sol(5.9)),
197-
'identity balance is greater than 5.9'
187+
isEqualToAmount(derivedBalance, sol(1), sol(0.01)),
188+
'derived balance is around 1'
198189
);
199-
t.ok(isEqualToAmount(derivedBalance, sol(1)), 'derived balance is 1');
200190
});
201191

202192
test('[derivedIdentity] it can withdraw everything from the derived identity', async (t: Test) => {
@@ -216,12 +206,8 @@ test('[derivedIdentity] it can withdraw everything from the derived identity', a
216206
// It's a little less due to the transaction fee.
217207
const { identityBalance, derivedBalance } = await getBalances(mx);
218208
t.ok(
219-
isLessThanAmount(identityBalance, sol(7)),
220-
'identity balance is less than 7'
221-
);
222-
t.ok(
223-
isGreaterThanAmount(identityBalance, sol(6.9)),
224-
'identity balance is greater than 6.9'
209+
isEqualToAmount(identityBalance, sol(7), sol(0.01)),
210+
'derived balance is around 7'
225211
);
226212
t.ok(isEqualToAmount(derivedBalance, sol(0)), 'derived balance is 0');
227213
});

0 commit comments

Comments
 (0)