|
1 | 1 | --- |
2 | | -title: "How to find" |
| 2 | +title: "How to find Jetton wallet" |
3 | 3 | --- |
4 | 4 |
|
5 | | -Stub |
| 5 | +Some application may want to be able to discover their or other contract wallets for some specific Jetton Master. |
| 6 | +For instance some contract may want to obtain and store its jetton wallet for some Jetton to handle transfer notifications from it in specific way. |
| 7 | + |
| 8 | +To compute the address of a Jetton wallet from the address of its owner (a regular user wallet), |
| 9 | +the Jetton master contract provides the `get_wallet_address (slice owner_address)` method. |
| 10 | + |
| 11 | +```typescript |
| 12 | +import { TonClient, Address, beginCell, TupleItemSlice } from "@ton/ton"; |
| 13 | + |
| 14 | +async function main() { |
| 15 | + const client = new TonClient({ |
| 16 | + endpoint: "https://toncenter.com/api/v2/jsonRPC", |
| 17 | + }); |
| 18 | + const jettonMasterAddress = Address.parse( |
| 19 | + "put the Jetton master address in any format", |
| 20 | + ); |
| 21 | + const walletAddress = Address.parse("put owner's address in any format"); |
| 22 | + const walletAddressCell = beginCell().storeAddress(walletAddress).endCell(); |
| 23 | + // forming the required type for the stack |
| 24 | + const el: TupleItemSlice = { |
| 25 | + type: "slice", |
| 26 | + cell: walletAddressCell, |
| 27 | + }; |
| 28 | + // call the get method with a non-empty stack |
| 29 | + const data = await client.runMethod( |
| 30 | + jettonMasterAddress, |
| 31 | + "get_wallet_address", |
| 32 | + [el], |
| 33 | + ); |
| 34 | + // get the Jetton wallet address |
| 35 | + console.log(data.stack.readAddress()); |
| 36 | +} |
| 37 | + |
| 38 | +void main(); |
| 39 | +``` |
| 40 | + |
| 41 | +Or if you are sure about structure of Jetton wallet's initial persistent storage and know its code, you |
| 42 | +can also manually create `StateInit` of the Jetton wallet and thus calculate its address. |
| 43 | + |
| 44 | +<Warning> |
| 45 | + Use this method with great care, as the c4 of Jetton wallet contracts is not specified. |
| 46 | +</Warning> |
| 47 | + |
| 48 | +```typescript |
| 49 | +import { |
| 50 | + Address, |
| 51 | + Cell, |
| 52 | + beginCell, |
| 53 | + contractAddress, |
| 54 | + StateInit, |
| 55 | +} from "@ton/core"; |
| 56 | + |
| 57 | +// let's choose Thether USDT as an example |
| 58 | + |
| 59 | +const jettonwalletcode = Cell.fromHex( |
| 60 | + "b5ee9c72010101010023000842028f452d7a4dfd74066b682365177259ed05734435be76b5fd4bd5d8af2b7c3d68", |
| 61 | +); |
| 62 | + |
| 63 | +const masterAddress = Address.parse( |
| 64 | + "0:b113a994b5024a16719f69139328eb759596c38a25f59028b146fecdc3621dfe", |
| 65 | +); |
| 66 | +const ownerAddress = Address.parse("an address in any format"); |
| 67 | +const jettonwalletdata = beginCell() |
| 68 | + .storeAddress(ownerAddress) |
| 69 | + .storeAddress(masterAddress) |
| 70 | + .storeVarUint(0, 16) // the initial value is always zero |
| 71 | + .endCell(); |
| 72 | + |
| 73 | +const jettonWalletStateInit: StateInit = { |
| 74 | + code: jettonwalletcode, |
| 75 | + data: jettonwalletdata, |
| 76 | +}; |
| 77 | + |
| 78 | +const BASECHAIN = 0; // All Jetton wallet contracts are located in Basechain by default |
| 79 | +const jettonWalletAddress = contractAddress(BASECHAIN, jettonWalletStateInit); |
| 80 | + |
| 81 | +console.log(jettonWalletAddress.toString()); |
| 82 | +``` |
| 83 | + |
| 84 | +There are also various web services that allow you to call contract's get methods without writing any code. |
| 85 | +For example, let's inspect the [Tether USD](https://tonviewer.com/EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs?section=method) master |
| 86 | +contract page on Tonviewer. Inserting owner's address in any format and executing the get method, you obtain the Jetton wallet address. |
| 87 | + |
| 88 | + |
| 89 | + |
| 90 | +Finally, you can use [built-in APIs](/ecosystem/rpc/toncenter). |
0 commit comments