# Paymaster SDK Tutorial (Typescript)

```typescript
npm install @kanalabs/paymaster-sdk
or
yarn add @kanalabs/paymaster-sdk
```

## Initialize SDK with Private Key and projectKey

```typescript
import { PaymasterSdk } from "@kanalabs/paymaster-sdk";
const sdk = new PaymasterSdk(
  {
    privateKey:
      "user private key", // Optional
  },
  { 
    projectKey: "your project key", 
    network: Network.TESTNET // default MAINNET 
    chain: chainName.Aptos  // default aptos chain
  }
);
```

### Initialize SDK without Private Key

```typescript
import { PaymasterSdk } from "@kanalabs/paymaster-sdk";
const sdk = new PaymasterSdk({}, { projectKey: testProjectKey, network: Network.TESTNET })
```

## Check If user already whitelisted,

```typescript
const isWhitelisted = await sdk.isWhitelisted();

// Response format
{
    success: boolean;
    message: string;
}
```

It will return `{ success: true, message: 'whitelisted' }` if already whitelisted.

It will return `{ success: true, message: 'not whitelisted' }` if it is not whitelisted.

## To add user to whitelist

```typescript
const whitelist = await sdk.addToWhitelist();
// Response format
{
    success: boolean;
    message: string;
}
```

It will return `{ success: true, message: 'Successfully added' }` if successfully whitelisted.

It will return `{ success: true, message: 'already whitelisted' }` if user already whitelisted.

## Initialize user account&#x20;

if that account is not available in Aptos mainnet you can initialize account with the following function.

```typescript
const initAccount = await sdk.initAccount();
// Response format
{
    success: boolean;
    message: string;
}
```

It will return `{ success: true, message: 'account initialized' }` if successfully initialized.

## Sponsor Transactions for Aptos

To make sponsored transactons you can build they required payload and pass it to the `sponsoredTxn`&#x20;

```typescript
const payload: TransactionPayload = {
    function: "0x1::aptos_account::transfer_coins",
    functionArguments: [
      "0xa197f0ffe941bf5cfca7af28438c8692464316fd8075baf6145c26051bc85d4d",
      0,
    ],
    typeArguments: ["0x1::aptos_coin::AptosCoin"],
  };
```

```typescript
  const options: TransactionOptions = { gasUnitPrice: 100, maxGasAmount: 2000 };
```

```typescript
try {
  const txn = await sdk.sponsoredTxn({
    data: payload,
    options: options,
  })
  if ((txn as PendingTransactionResponse).hash) {
    const txnReceipt = await sdk.aptosClient.waitForTransaction({
      transactionHash: (txn as PendingTransactionResponse).hash,
      options: {
        checkSuccess: true,
      },
    })
    console.log(txnReceipt.success)
  }
  } catch (error: any) {
    console.log("error", error);
  }
```

## Sponsor Transactions for Supra

<pre class="language-typescript"><code class="lang-typescript"><strong>  const testProjectKey = process.env.PROJECT_KEY as string
</strong>  const testPrivateKey = process.env.PRIVATE_KEY as string
  const privateKeyWithoutPrefix = testPrivateKey.replace(/^0x/, '')
  const account = new SupraAccount(Buffer.from(privateKeyWithoutPrefix, 'hex'))

  const receiverAddress = new HexString(
    // "1000000000000000000000000000000000000000000000000000000000000000"
    '0xded95a2323d6fd7509891ee6f88f265066723ba06762f13a8c67796ff40be40d',
  )
  
  const key = account?.toPrivateKeyObject().privateKeyHex

  const sdk = new PaymasterSdk(
    { privateKey: key },
    { projectKey: testProjectKey, network: Network.TESTNET, chain: chainName.Supra },
  )

  const feePayerAccount: any = await sdk.getDappFeePayerAddress()
  const feepayerAccountAddress = new HexString(feePayerAccount?.feePayerAddress[0]?.address.toString())

  const payloadData: SupraPayload = {
    module_address: '0000000000000000000000000000000000000000000000000000000000000001',
    module_name: 'supra_account',
    function_name: 'transfer',
    type_arguments: [],
    arguments: [receiverAddress.toUint8Array(), BCS.bcsSerializeUint64(0)],
  }

  const isWhitelisted = await sdk.isWhitelisted()
  if (!(isWhitelisted.message == 'whitelisted')) {
    console.log(await sdk.addToWhitelist())
    console.log(await sdk.initAccount())
  }

  const sponsorTxSupraCoinTransferRawTransaction = await sdk.SupraClient.createRawTxObject(
    await sdk.wallet.accountAddress,
    (await sdk.SupraClient.getAccountInfo(await sdk.wallet.accountAddress)).sequence_number,
    payloadData.module_address,
    payloadData.module_name,
    payloadData.function_name,
    payloadData.type_arguments,
    [payloadData.arguments[0], payloadData.arguments[1]],
  )

  // Creating Sponsor Transaction Payload
  const sponsorTransactionPayload = new TxnBuilderTypes.FeePayerRawTransaction(
    sponsorTxSupraCoinTransferRawTransaction,
    [],
    new TxnBuilderTypes.AccountAddress(feepayerAccountAddress.toUint8Array()),
  )

  const sign = SupraClient.signSupraMultiTransaction(account, sponsorTransactionPayload)

  const txn = await sdk.sponsoredTxn({
    data: payloadData,
    senderAddress: account.address().toString(),
    senderAuth: sign,
    transaction: sponsorTransactionPayload.raw_txn,
  })
  console.log('txn: ', txn)
</code></pre>

## Sponsor Transaction with Sender Auth and Transaction for Aptos

```typescript
    const config = new AptosConfig({ network: Network.MAINNET })
    const aptosClient = new Aptos(config)
    const senderAccount = Account.generate()

    const payload: TransactionPayload = {
      function: '0x1::aptos_account::transfer_coins',
      functionArguments: ['0x0b4b8ef78fb296f89006f1936f01427a3a7e0eadd11dd4998c6bf438a0c8ce6b', 0],
      typeArguments: ['0x1::aptos_coin::AptosCoin'],
    }

    const options: TransactionOptions = {
      gasUnitPrice: 100,
      maxGasAmount: 2000,
    }

    const sdk = new PaymasterSdk(
      { privateKey: undefined },
      {
        projectKey: testProjectKey,
        network: Network.MAINNET,
        // by default chain is aptos
      },
    )

    const isWhitelisted = await sdk.isWhitelisted({
      address: senderAccount.accountAddress.toString(),
    })

    if (!(isWhitelisted.message == 'whitelisted')) {
      console.log('not whitelisted')
      console.log(
        await sdk.addToWhitelist({
          address: senderAccount.accountAddress.toString(),
        }),
      )
    }
    console.log(
      await sdk.initAccount({
        address: senderAccount.accountAddress.toString(),
      }),
    )

    const transaction = await aptosClient.transaction.build.simple({
      sender: senderAccount.accountAddress.toString(),
      data: payload,
      options: options,
      withFeePayer: true,
    })
    const senderAuth = sdk.aptosClient.transaction.sign({
      signer: senderAccount,
      transaction: transaction,
    })

    const response = await sdk.sponsoredTxnWithSenderAuth({
      senderAuth: senderAuth,
      transaction: transaction,
    })
    if ((response as PendingTransactionResponse).hash) {
      const txnreceipt = (await sdk.aptosClient.waitForTransaction({
        transactionHash: (response as PendingTransactionResponse).hash,
        options: { checkSuccess: true },
      })) as UserTransactionResponse
      console.log('txn status', txnreceipt.success)
    }
```

## Sponsor Transaction with Sender Auth and Transaction for Supra

```typescript
try {
    const testProjectKey = process.env.PROJECT_KEY as string
    const testPrivateKey = process.env.PRIVATE_KEY as string
    const privateKeyWithoutPrefix = testPrivateKey.replace(/^0x/, '')
    const sdk = new PaymasterSdk(
      { privateKey: undefined },
      {
        projectKey: testProjectKey,
        network: Network.TESTNET,
        chain: chainName.Supra,
      },
    )

    const senderAccount = new SupraAccount(Buffer.from(privateKeyWithoutPrefix, 'hex'))

    const sender = senderAccount.address().toString()

    const receiverAddress = new HexString(
      '0xded95a2323d6fd7509891ee6f88f265066723ba06762f13a8c67796ff40be40d',
    )

    const feePayerAccount: any = await sdk.getDappFeePayerAddress()
    const feepayerAccountAddress = new HexString(feePayerAccount?.feePayerAddress[0]?.address.toString())

    const isWhitelisted = await sdk.isWhitelisted({
      address: sender,
    })

    if (!(isWhitelisted.message == 'whitelisted')) {
      console.log('not whitelisted')
      console.log(
        await sdk.addToWhitelist({
          address: sender,
        }),
        await sdk.initAccount({ address: sender }),
      )
    }

    const sponsorTxSupraCoinTransferRawTransaction = await sdk.SupraClient.createRawTxObject(
      senderAccount.address(),
      (await sdk.SupraClient.getAccountInfo(senderAccount.address())).sequence_number,
      '0000000000000000000000000000000000000000000000000000000000000001',
      'supra_account',
      'transfer',
      [],
      [receiverAddress.toUint8Array(), BCS.bcsSerializeUint64(0)],
    )

    // Creating Sponsor Transaction Payload
    const sponsorTransactionPayload = new TxnBuilderTypes.FeePayerRawTransaction(
      sponsorTxSupraCoinTransferRawTransaction,
      [],
      new TxnBuilderTypes.AccountAddress(feepayerAccountAddress.toUint8Array()),
    )

    const sign = SupraClient.signSupraMultiTransaction(senderAccount, sponsorTransactionPayload)

    const response = await sdk.sponsoredTxnWithSenderAuth({
      senderAuth: sign,
      senderAddress: sender,
      transaction: sponsorTransactionPayload.raw_txn,
    })
    console.log('response: ', response)
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.kanalabs.io/~/changes/JpxQ3y4p9AD4BHUqimHx/paymaster-service/kana-paymaster-for-aptos-and-supra/paymaster-sdk-tutorial-typescript.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
