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

Commit 49c53ad

Browse files
dbouresjoncinque
andauthored
token-js: Add sync version of getAssociatedTokenAddress (#3171)
* token-js: Bump web3.js dependency to 1.41.0 * token-js: Add sync version of getAssociatedTokenAddress * token-js: add test for getAssociatedTokenAddressSync * Update lockfile Co-authored-by: Jon Cinque <[email protected]>
1 parent 895747f commit 49c53ad

File tree

4 files changed

+89
-30
lines changed

4 files changed

+89
-30
lines changed

token/js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"dependencies": {
4343
"@solana/buffer-layout": "^4.0.0",
4444
"@solana/buffer-layout-utils": "^0.2.0",
45-
"@solana/web3.js": "^1.36.0",
45+
"@solana/web3.js": "^1.41.0",
4646
"start-server-and-test": "^1.14.0"
4747
},
4848
"devDependencies": {

token/js/src/state/mint.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,16 @@ export async function getMinimumBalanceForRentExemptMintWithExtensions(
133133
}
134134

135135
/**
136-
* Get the address of the associated token account for a given mint and owner
136+
* Async version of getAssociatedTokenAddressSync
137+
* For backwards compatibility
137138
*
138139
* @param mint Token mint account
139140
* @param owner Owner of the new account
140141
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
141142
* @param programId SPL Token program account
142143
* @param associatedTokenProgramId SPL Associated Token program account
143144
*
144-
* @return Address of the associated token account
145+
* @return Promise containing the address of the associated token account
145146
*/
146147
export async function getAssociatedTokenAddress(
147148
mint: PublicKey,
@@ -159,3 +160,31 @@ export async function getAssociatedTokenAddress(
159160

160161
return address;
161162
}
163+
164+
/**
165+
* Get the address of the associated token account for a given mint and owner
166+
*
167+
* @param mint Token mint account
168+
* @param owner Owner of the new account
169+
* @param allowOwnerOffCurve Allow the owner account to be a PDA (Program Derived Address)
170+
* @param programId SPL Token program account
171+
* @param associatedTokenProgramId SPL Associated Token program account
172+
*
173+
* @return Address of the associated token account
174+
*/
175+
export function getAssociatedTokenAddressSync(
176+
mint: PublicKey,
177+
owner: PublicKey,
178+
allowOwnerOffCurve = false,
179+
programId = TOKEN_PROGRAM_ID,
180+
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
181+
): PublicKey {
182+
if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer())) throw new TokenOwnerOffCurveError();
183+
184+
const [address] = PublicKey.findProgramAddressSync(
185+
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
186+
associatedTokenProgramId
187+
);
188+
189+
return address;
190+
}

token/js/test/unit/index.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
TokenOwnerOffCurveError,
1414
getAccountLen,
1515
ExtensionType,
16+
getAssociatedTokenAddressSync,
1617
} from '../../src';
1718

1819
chai.use(chaiAsPromised);
@@ -117,6 +118,43 @@ describe('state', () => {
117118
new PublicKey('F3DmXZFqkfEWFA7MN2vDPs813GeEWPaT6nLk4PSGuWJd').toString()
118119
);
119120
});
121+
122+
it('getAssociatedTokenAddressSync matches getAssociatedTokenAddress', async () => {
123+
const asyncAssociatedPublicKey = await getAssociatedTokenAddress(
124+
new PublicKey('7o36UsWR1JQLpZ9PE2gn9L4SQ69CNNiWAXd4Jt7rqz9Z'),
125+
new PublicKey('B8UwBUUnKwCyKuGMbFKWaG7exYdDk2ozZrPg72NyVbfj')
126+
);
127+
const associatedPublicKey = getAssociatedTokenAddressSync(
128+
new PublicKey('7o36UsWR1JQLpZ9PE2gn9L4SQ69CNNiWAXd4Jt7rqz9Z'),
129+
new PublicKey('B8UwBUUnKwCyKuGMbFKWaG7exYdDk2ozZrPg72NyVbfj')
130+
);
131+
expect(associatedPublicKey.toString()).to.eql(
132+
new PublicKey('DShWnroshVbeUp28oopA3Pu7oFPDBtC1DBmPECXXAQ9n').toString()
133+
);
134+
expect(asyncAssociatedPublicKey.toString()).to.eql(associatedPublicKey.toString());
135+
136+
expect(function () {
137+
getAssociatedTokenAddressSync(
138+
new PublicKey('7o36UsWR1JQLpZ9PE2gn9L4SQ69CNNiWAXd4Jt7rqz9Z'),
139+
associatedPublicKey
140+
);
141+
}).to.throw(TokenOwnerOffCurveError);
142+
143+
const asyncAssociatedPublicKey2 = await getAssociatedTokenAddress(
144+
new PublicKey('7o36UsWR1JQLpZ9PE2gn9L4SQ69CNNiWAXd4Jt7rqz9Z'),
145+
asyncAssociatedPublicKey,
146+
true
147+
);
148+
const associatedPublicKey2 = getAssociatedTokenAddressSync(
149+
new PublicKey('7o36UsWR1JQLpZ9PE2gn9L4SQ69CNNiWAXd4Jt7rqz9Z'),
150+
associatedPublicKey,
151+
true
152+
);
153+
expect(associatedPublicKey2.toString()).to.eql(
154+
new PublicKey('F3DmXZFqkfEWFA7MN2vDPs813GeEWPaT6nLk4PSGuWJd').toString()
155+
);
156+
expect(asyncAssociatedPublicKey2.toString()).to.eql(associatedPublicKey2.toString());
157+
});
120158
});
121159

122160
describe('extensionType', () => {

token/js/yarn.lock

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -136,33 +136,28 @@
136136
bigint-buffer "^1.1.5"
137137
bignumber.js "^9.0.1"
138138

139-
"@solana/buffer-layout@^3.0.0":
140-
version "3.0.0"
141-
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-3.0.0.tgz#b9353caeb9a1589cb77a1b145bcb1a9a93114326"
142-
integrity sha512-MVdgAKKL39tEs0l8je0hKaXLQFb7Rdfb0Xg2LjFZd8Lfdazkg6xiS98uAZrEKvaoF3i4M95ei9RydkGIDMeo3w==
143-
dependencies:
144-
buffer "~6.0.3"
145-
146139
"@solana/buffer-layout@^4.0.0":
147140
version "4.0.0"
148141
resolved "https://registry.yarnpkg.com/@solana/buffer-layout/-/buffer-layout-4.0.0.tgz#75b1b11adc487234821c81dfae3119b73a5fd734"
149142
integrity sha512-lR0EMP2HC3+Mxwd4YcnZb0smnaDw7Bl2IQWZiTevRH5ZZBZn6VRWn3/92E3qdU4SSImJkA6IDHawOHAnx/qUvQ==
150143
dependencies:
151144
buffer "~6.0.3"
152145

153-
"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.36.0":
154-
version "1.36.0"
155-
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.36.0.tgz#79d7d5217b49b80139f4de68953adc5b9a9a264f"
156-
integrity sha512-RNT1451iRR7TyW7EJKMCrH/0OXawIe4zVm0DWQASwXlR/u1jmW6FrmH0lujIh7cGTlfOVbH+2ZU9AVUPLBFzwA==
146+
"@solana/web3.js@^1.32.0", "@solana/web3.js@^1.41.0":
147+
version "1.41.10"
148+
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.41.10.tgz#fb1bf7d8ca25f126a2166fed1733fe357298a076"
149+
integrity sha512-2mPNoxGDt5jZ4MYA+aK7qKzvdXdN0niy7suYfkbrcgAWahJ/WSfPD2W0IvySDdLLfCQojSs7sdHIW+xsKV9dyQ==
157150
dependencies:
158151
"@babel/runtime" "^7.12.5"
159152
"@ethersproject/sha2" "^5.5.0"
160-
"@solana/buffer-layout" "^3.0.0"
153+
"@solana/buffer-layout" "^4.0.0"
154+
"@solana/buffer-layout-utils" "^0.2.0"
161155
bn.js "^5.0.0"
162-
borsh "^0.4.0"
156+
borsh "^0.7.0"
163157
bs58 "^4.0.1"
164158
buffer "6.0.1"
165159
cross-fetch "^3.1.4"
160+
fast-stable-stringify "^1.0.0"
166161
jayson "^3.4.4"
167162
js-sha3 "^0.8.0"
168163
rpc-websockets "^7.4.2"
@@ -190,13 +185,6 @@
190185
resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.2.tgz#423c77877d0569db20e1fc80885ac4118314010e"
191186
integrity sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==
192187

193-
"@types/bn.js@^4.11.5":
194-
version "4.11.6"
195-
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c"
196-
integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==
197-
dependencies:
198-
"@types/node" "*"
199-
200188
"@types/chai-as-promised@^7.1.4":
201189
version "7.1.4"
202190
resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.4.tgz#caf64e76fb056b8c8ced4b761ed499272b737601"
@@ -553,18 +541,17 @@ bn.js@^4.11.9:
553541
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
554542
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
555543

556-
bn.js@^5.0.0:
544+
bn.js@^5.0.0, bn.js@^5.2.0:
557545
version "5.2.0"
558546
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002"
559547
integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==
560548

561-
borsh@^0.4.0:
562-
version "0.4.0"
563-
resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.4.0.tgz#9dd6defe741627f1315eac2a73df61421f6ddb9f"
564-
integrity sha512-aX6qtLya3K0AkT66CmYWCCDr77qsE9arV05OmdFpmat9qu8Pg9J5tBUPDztAW5fNh/d/MyVG/OYziP52Ndzx1g==
549+
borsh@^0.7.0:
550+
version "0.7.0"
551+
resolved "https://registry.yarnpkg.com/borsh/-/borsh-0.7.0.tgz#6e9560d719d86d90dc589bca60ffc8a6c51fec2a"
552+
integrity sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==
565553
dependencies:
566-
"@types/bn.js" "^4.11.5"
567-
bn.js "^5.0.0"
554+
bn.js "^5.2.0"
568555
bs58 "^4.0.0"
569556
text-encoding-utf-8 "^1.0.2"
570557

@@ -1136,6 +1123,11 @@ fast-levenshtein@^2.0.6:
11361123
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
11371124
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
11381125

1126+
fast-stable-stringify@^1.0.0:
1127+
version "1.0.0"
1128+
resolved "https://registry.yarnpkg.com/fast-stable-stringify/-/fast-stable-stringify-1.0.0.tgz#5c5543462b22aeeefd36d05b34e51c78cb86d313"
1129+
integrity sha1-XFVDRisiru79NtBbNOUceMuG0xM=
1130+
11391131
fastq@^1.6.0:
11401132
version "1.13.0"
11411133
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"

0 commit comments

Comments
 (0)